2012年3月3日土曜日

HomebrewでインストールしたJenkinsのHTTP listen portを変更する方法

Homebrewでインストールする方法自体はこのあたりを参考に。
~/Library/LaunchAgents/にコピーしたhomebrew.mxcl.jenkins.plistファイルの中を見るとこんな感じになっている。


jenkins.war-jarオプションで起動しているので、これはWinstoneをサーブレットコンテナとして動作している。なので、Winstoneの起動オプションを追加すればそれを読み取ってくれるようだ。以下はlisten portの変更を変更するオプションを追加したもの。


別途試していたScalatraが先に8080を使っていたので、とりあえず18080に引っ越してもらった。

変更はプロセスの再起動後に反映される。

launchctl unload ~/Library/LaunchAgents/homebrew.mxcl.jenkins.plist
launchctl load ~/Library/LaunchAgents/homebrew.mxcl.jenkins.plist

本格運用するには不十分だろうが、とりあえず試してみるにはこれで十分かと。

2012年2月28日火曜日

mapBetween関数Scala版 その4(完結編)

昨日のポストのコードに対して、がくぞさんからまさにそれが欲しかったという修正を頂いたので掲載。



traitとして別途宣言せず、mapBetween関数が追加された無名クラスのインスタンスを返すようにimplicit conversionを定義する。(3〜7行目)
Seqのサブクラスとして何が来ようと、そのクラスを拡張した形で無名クラスが定義されるため、返り値がmutableになってしまうこともない。何より大変シンプルになってわかりやすい。

今度のseqToExtSeq関数の返り値は無名クラスのインスタンスになるため、返り値の型を明示できない。そのためか、main関数の後に定義すると、以下のようなエラーが出てコンパイル出来なかった。

value mapBetween is not a member of scala.collection.immutable.Range.Inclusive  Note: implicit method seqToExtSeq is not applicable here because it comes after the application point and it lacks an explicit result type mapBetween.scala
順番が入れ替わっているのはそのため。

とりあえず最初の手習いとしてはこれくらいにして、次は別のことをやってみる。

2012年2月27日月曜日

mapBetween関数Scala版 その3

前回で関数の実装はまともになったので、クラスを拡張する方向に検討をしてみる。


とりあえずmapBetween関数をtraitにして分離。(20〜24行目)
前回までは、型パラメタAを下限とする型パラメタTを関数の引数の型としていたが、traitにしたことでまたうまく関数の型推論ができなくなってかえって使いにくいため、Aそのものを引数の型に変更した。匿名関数が手軽に定義できる以上、JavaのComparatorのような問題は起きないと思って良いのかもしれない。

使う際にはSeqのサブクラスをnewする時にwith ExtSeq[A]でtraitをミックスインする(3行目)ことで、mapBetween関数を呼び出すことができるようになる。(4〜6行目)
ミックスインできるのはインスタンス化するときなので、生成されたインスタンスを返すRichIntクラスのtoメソッドは使えない。Rangeクラスのコンストラクタはfrom, to, stepの3つの引数を必ず要求するため、ちょっと使いにくい。

そこで、Seqのサブクラスのインスタンスを trait ExtSeqをミックスインしたクラスのインスタンスに変換する、暗黙の型変換を行う関数を定義する。(14〜17行目)

この暗黙の型変換は、mapBetweenオブジェクトのスコープ内で有効なため、Rangeクラスのインスタンスを普通に生成(8行目)しても、そのインスタンスに対してmapBetween関数を呼び出そうとすることで、コンパイル時に暗黙的にseqToExtSeq関数の呼び出しが加えられる。それによって、あたかもRangeクラスに元々mapBetween関数が定義されていたかのように見える。(9〜12行目)

このseqToExtSeq関数を定義する際に注意することは、返り値をExtSeqにしなければならないのを誤ってSeqのインスタンスを返すように実装(例えば++=の代わりに++を呼んでしまった等)しても、コンパイルが通ってしまうことだ。そうした場合、実行時にseqToExtSeq関数が呼び出されると、Seqのインスタンスを本来の返り値の型であるExtSeqに暗黙的に変換しようとして、自分を再帰的に呼び出してしまい、無限ループに陥る。しかもタチの悪いことに、末尾最適化されてしまってスタックがオーバフローしないため、ただダンマリになってしまってしばらく何が起きたのかわからなかった。実装時はimplicit修飾子を付けないで実装して、後から修飾子を付けたほうが間違いが起こりにくいかも。

ところで、immutableなパッケージでミックスインできるクラスが見つけられなかったためやむを得ずArrayBufferを使ってしまったが、このままでは暗黙の型変換をした後のインスタンスがmutableになってしまう。ココは改善する必要があるのだが、とりあえずノーアイディア。

2012年2月24日金曜日

mapBetween関数Scala版 その2

前回のコードをrpscalaの方々に見て頂いたところ、「それ、slidingでできるよ!」と教えていただいたので修正。


sliding関数は引数で指定された個数を1つのブロックとして、sliding windowを提供する。例えばSeq(1,2,3,4)に対してsliding(2)を呼び出すと、Seq(1,2),Seq(2,3),Seq(3,4)と返すIteratorが返される。sliding(3)ならSeq(1,2,3),Seq(2,3,4)となる。
これはmapBetween関数でやりたいことほぼそのものなので、結果としてえらいシンプルになってしまった。

前回適用する関数に対して型推論が効かないと愚痴ったが、これはカリー化することで対応できることを教えてもらった。カリー化前だと型パラメタAとTを同時に推論しなければならず、それが上手くいかない原因だった模様。カリー化することで先に型Aが決定するため、型Tが上手く推論できるようになるらしい。嘘かも。型推論はもうちょっとまともに勉強したいなぁ。。。

2012年1月27日金曜日

mapBetween関数Scala版

dankogai先生の投稿 algorithm - mapBetween - 配列の隣接する2項にそれぞれ演算を施した配列 にあるmapBetween関数をScalaで書いてみる。
クラスを拡張する形で書きたかったのだが、いっぺんにやろうとするときっとこんがらがるのでとりあえずSeqを引数で受ける形で実装。


とりあえず動くけど、果たして効率の良い実装になっているのか。。。
隣り合う2項に適用する関数のパラメタに、型を指定しなければコンパイルが通らない。第1引数Seqの型パラメタから推論して欲しいところだけどどうもそうはならないみたい。
foldLeftの左項のタプルの1つめの要素で、Seq[B]()の代わりにNilを指定したかったのだが、型の不一致でこれもまたコンパイルが通らない。まぁこちらはなんとなく仕方がない気がする。