moinmoin更新
moinmoinを1.84から1.93に更新した。
行った作業は以下の通りである。
キャッシュをクリア
キャッシュをクリアしないとInternal errorが発生した。
以下のコマンドでクリアした。/usr/share/moin/moinmoinはmoinmoinのデータディレクトリである。ここをカレントにして実行しないとうまく動かなかった。
sudo sh -c 'cd /usr/share/moin/moinmoin && moin --config-dir=/etc/moin --wiki-url=http://localhost/mywiki/ maint cleancache'
[プログラミング] [git] git rmの取り消し
以下のようにgit rmでファイルを消した場合
$ git rm hoge/hoge.c # 削除
以下で復活できる。
$ git reset HEAD hoge/hoge.c # キャッシュ上で復活 $ git checkout hoge/hoge.c # ファイルの取り出し
git statusを見たら書いてあった。地味に親切だのう
setup.pyの拡張
pythonのプログラムを書いたらsetup.pyでインストールできるようにしよう!ということで書いたけどMakefileのがよくね?とかそんな疑問を持ちつつほげー
やりたいこと
- 適当なコマンドの追加
- setup()のattrs引数で、このコマンドの対象とするファイルを指定する
- buildを実行すると、追加したコマンドを実行する
- cleanを実行すると、追加したコマンドの生成したファイルを削除する
まず、コマンドの追加方法。distutils.cmd.Commandを派生させる。
from distutils.cmd import Command class MyCommand(Command): # 以下のクラス変数は宣言しないと怒られる description = 'My command' user_options = [] def initialize_options(self): pass def finalize_options(self): pass def run(self): print('Do my command.')
initialize_option, finalize_options, runをoverwrideする。実行したい処理はrunに記述する。その上で、setup()のcmdclassにコマンド名とともに作成したクラスを指定する。
from distutils.core import setup setup( cmdclass = {'mycommand': MyCommand} )
以上でmycommandが実行可能に
$ ./setup.py mycommand running mycommand Do my command.
つぎに、コマンドの中からsetup()に独自の引数を追加し、MyCommandの中から参照する。具体的には以下のように、greetingを指定したらその内容を出力するようにしてみる。
setup(cmdclass = {'mycommand': MyCommand }, name = 'hoge', version = '1.0.0', packages = [ 'hoge' ], greeting = 'Popopopoooon' )
まず、Distributionを派生させて、インスタンス変数を追加する。ここでの注意は、スーパークラスの__init__()を呼ぶ前にインスタンス変数を作っておくこと。つまり、スーパークラスの__init__()でそれっぽい処理が走ってる。
from distutils.dist import Distribution class MyDistribution(Distribution): def __init__(self, attrs=None): self.greeting= None Distribution.__init__(self, attrs)
次に、MyCommandでそれを取得する。
from distutils.cmd import Command class MyCommand(Command): # 以下のクラス変数は宣言しないと怒られる description = 'My command' user_options = [] def initialize_options(self): self.greeting = None def finalize_options(self): self.greeting = self.distribution.greeting def run(self): print(self.greeting)
で、このクラスをsetup()のdistclassに指定。
setup(distclass = MyDistribution, cmdclass = {'mycommand': MyCommand }, name = 'hoge', version = '1.0.0', packages = [ 'hoge' ], greeting = 'Popopopoooon' )
実行!
$ ./setup.py mycommand running mycommand Popopopoooon
最後に以下の2つ
- buildを実行すると、追加したコマンドを実行する
- cleanを実行すると、追加したコマンドの生成したファイルを削除する
やってることは同じで、デフォルトのコマンドのrun()を上書きしている。
from distutils.command.build import build from distutils.command.clean import clean class MyBuild(build): def run(self): self.run_command('mycommand') return build.run(self) class MyClean(clean): def run(self): clean.run(self) if self.all: print('Remove nanka')
MyBuildではself.run_command()でmycommandを実行している。
また、MyCleanでは一応、--allオプションが指定されたときだけ処理が走るように、self.allを見ている。
で、最後にsetup()のcmdclassに作ったクラスを指定する。
setup(distclass = MyDistribution, cmdclass = {'mycommand': MyCommand, 'build': MyBuild, 'clean': MyClean }, name = 'hoge', version = '1.0.0', packages = [ 'hoge' ], greeting = 'Popopopoooon' )
実行!
$ ./setup.py build running build running mycommand Popopopoooon running build_py $ ./setup.py clean --all running clean removing 'build/lib.linux-x86_64-2.6' (and everything under it) 'build/bdist.linux-x86_64' does not exist -- can't clean it 'build/scripts-2.6' does not exist -- can't clean it removing 'build' Remove nanka
しかし、makeから劣化してねーかなぁ…
mapのタイミング
mapが実行されるタイミングの確認。
val a = List(1, 2, 3) def withPrint(x: Int): Int = { println(x) x } println("List Map") val b = a.map(withPrint) println("foreach") b.foreach { x => println("1st loop %s".format(x)); } println("foreach") b.foreach { x => println("2nd loop %s".format(x)); } println("Iterator Map") val it = a.iterator.map(withPrint) println("foreach") it.foreach { x => println("1st loop %s".format(x)); } println("foreach") it.foreach { x => println("2nd loop %s".format(x)); } println("Stream Map") val strm = Stream.concat(a).map(withPrint) println("foreach") strm.foreach { x => println("1st loop %s".format(x)); } println("foreach") strm.foreach { x => println("2nd loop %s".format(x)); }
上記のコードを実行すると以下の出力がでるため、
Listのmap | その場で計算 |
iteratorのmap | 値が必要になったら計算する。だたし、値を2回以上参照できない |
Streamのmap | 最初の要素だけその場で計算し、以降は必要になったら計算。 |
のタイミングでmapにくべた関数が実行されるよう
List Map 1 2 3 foreach 1st loop 1 1st loop 2 1st loop 3 foreach 2nd loop 1 2nd loop 2 2nd loop 3 Iterator Map foreach 1 1st loop 1 2 1st loop 2 3 1st loop 3 foreach Stream Map 1 foreach 1st loop 1 2 1st loop 2 3 1st loop 3 foreach 2nd loop 1 2nd loop 2 2nd loop 3
[プログラミング] 配列の比較
Array型を==で比較すると参照の比較になる。Seqあたりに型変換したあとに比較すると、Listなどと同じように内容を比較できる。
scala> val a = Array(1, 2, 3) a: Array[Int] = Array(1, 2, 3) scala> val b = Array(1, 2, 3) b: Array[Int] = Array(1, 2, 3) scala> a == b res2: Boolean = false scala> identity[Seq[Int]](a) == identity[Seq[Int]](a) res4: Boolean = true
identityは引数の値をそのまま返す関数。自動型変換を強要するために利用している。WrappedArrayとかなんとなく使いたくないので
[プログラミング] 暗黙の型変換とか暗黙の引数の確認
一体どの関数が呼ばれているのかわからないことに定評のあるscalaの自動型変換/暗黙の引数だが、コンパイル時に-Xprint:typerオプションを付与することで確認可能である。
implicit.scala
val a = Map("a" -> 1, "b" -> 2) a.map(_._2)
オプションをつけて実行
$ scala -Xprint:typer implicit.scala [[syntax trees at end of typer]]// Scala source: implicit.scala package <empty> { final object Main extends java.lang.Object with ScalaObject { def this(): object Main = { Main.super.this(); () }; def main(argv: Array[String]): Unit = { val args: Array[String] = argv; { final class $anon extends scala.AnyRef { def this(): anonymous class $anon = { $anon.super.this(); () }; private[this] val a: scala.collection.immutable.Map[java.lang.String,Int] = scala.this.Predef.Map.apply[java.lang.String, Int](scala.this.Predef.any2ArrowAssoc[java.lang.String]("a").->[Int](1), scala.this.Predef.any2ArrowAssoc[java.lang.String]("b").->[Int](2)); private <stable> <accessor> def a: scala.collection.immutable.Map[java.lang.String,Int] = $anon.this.a; $anon.this.a.map[Int, scala.collection.immutable.Iterable[Int]](((x$1: (java.lang.String, Int)) => x$1._2))(immutable.this.Iterable.canBuildFrom[Int]) }; { new $anon(); () } } } } }
これでmapメソッドの暗黙の引数にimmutable.this.Iterable.canBuildFrom[Int]が使われていることがわかる。