and演算子の短絡評価にはまった話

以下のコードで論理演算でなぜか右の関数funcが呼び出されてない><

    return a && func();

ってことになやまされ、とりあえず問題を分解するために

    auto f = func();
    return a && f;

としたら正常に動いた。
なんで?って思ってTwitterでつぶやいたら一瞬で反応がかえってきた。
どうやら短絡評価というらしい。
これはつまり評価の際「false && func()」の時点で答えはfuncの返す値にかかわらずfalseになってしまうのでここで評価をやめてfuncは永久に呼び出されないというもの。funcが重い処理だったりするときに便利だけどfuncがboolを返す以外の副作用をもってたりすると今回みたいに意図した結果を返さずハマる...評価させたいものはバラすか、あるいは左にもってくるかしないとダメということですね。

もう忘れない。踏みぬいたバグの数だけ強くなれるよね(と信じたい

CentOS6.3+nginxでJenkinsを導入した時のメモ

とりあえず入れてみたので手順メモ。
構成としてはnginxをリバースproxyにして、/jenkinsにきたものをjenkinsに転送させている。

まずjenkinsを入れる。

$sudo wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo
$sudo rpm --import http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key
$sudo yum install jenkins

また、jenkinsを動かすためにはjava-1.6.0とかがひつようなようなので入れる。

$sudo yum install java-1.6.0-openjdk

設定ファイルを編集。念の為バックアップをとっておく。

$sudo cp /etc/sysconfig/jenkins{,.bak}
$ sudo diff /etc/sysconfig/jenkins{,.bak}
133c133
< JENKINS_ARGS="--prefix=/jenkins --httpPort=${JENKINS_PORT} --ajp13Port=${JENKINS_AJP_PORT}"
---
> JENKINS_A||<RGS=""

つぎにnginxの設定。

$ sudo cp /usr/local/nginx/conf/<設定ファイル名>{,.bak}
$ sudo vim /usr/local/nginx/conf/<設定ファイル名>
$ sudo diff /usr/local/nginx/conf/<設定ファイル名>{,.bak}
13,16d12
<     	
< 	location /jenkins {
<       	    proxy_pass http://localhost:8080; 
<     	}

特に複雑な設定がいるわけではない(ちなみに実際の運用に使っているものには一応BASIC認証をかけた)

そして起動。

$sudo /etc/init.d/jenkins start
$ sudo /usr/local/nginx/sbin/nginx -s stop
$ sudo /usr/local/nginx/sbin/nginx

アクセスするとちゃんとうごいた。
とりあえずJenkinsちょっとつづ使っていこう。

iノード(inode)の使用量をディレクトリごとに表示するワンライナー

ファイルのメタ情報を格納するiノード(inode)というものがあるがこれが枯渇するとそれ以上ファイルが作れなくなってしまう。
iノードの数が少なくなってきた時どこが主にiノードを食っているのか確認したいことがあると思う。
が、特定ディレクトリのiノードを表示するコマンドは残念ながらない。
しかしiノードはファイル/ディレクトリに対して(ハードリンクをしない限り)ユニークに割り当てられるということを用いて大体の数を算出することができる。
以下がそのワンライナー。カレントディレクトリにあるディレクトリのiノードを表示してくれる。
使い方としてはdf -iでiノードが減少しているディスクをさがしそこのディレクトリに移動、肥大化しているディレクトリを調べる。
その肥大化しているディレクトリに移動...を繰り返して範囲を適切に狭めていく。

    for dir in `ll|grep ^d|grep -v "\./"|awk '{print $9}'`; do echo  `find ./$dir -true|wc -l` `pwd`/$dir; done | sort -nr

していることとしては

    ll|grep ^d|grep -v "\./"|awk '{print $9}'

でllの出力のうち先頭のパーミッションを解析してディレクトリのものをフィルタし、awkでディレクトリ名を取り出している。
ちなみにllのフォーマットがディストリビューションによって異なっていたり、そもそもなかったりするのでgrepawkの部分注意。
ls -lを使ったほうが無難かもしれない。

さてその結果の各行ごとに回しながら取り出して

    for dir in `ll|grep ^d|grep -v "\./"|awk '{print $9}'`

でdirに束縛する。

そして

    do echo `find ./$dir -true|wc -l` `pwd`/$dir

で./dir以下にあるファイルすべてを列挙しwc -lでその数を数えている。
あとは見やすいようにpwdとdirでそのディレクトリを表示している。
これだけでもいいがファイル数順(=iノードを消費している順)にならんだほうがみやすいのでsort -nrで並べ替える。

Kuinでlistに対するremoveとremove_ifを実装してみた

こんな感じ。
list操作と関数オブジェクトを受け取る関数の良いサンプルになってるんじゃないかと。

func remove(List : &list<int>, val : int)
	
	do List.Head()

  	while ( List .ChkEnd() <> true)
    if (List.Get() = val) 
		do List.Del()
	else
		do List.Next()
	end if
 	end while 
end func

func remove_if(List : &list<int>, pred : func<(int):bool>)
	
	do List.Head()

  	while ( List .ChkEnd() <> true)
    if (pred(List.Get())) 
		do List.Del()
	else
		do List.Next()
	end if
 	end while 
end func



func Main()
	var Data : list<int> :: #list<int>
	do Data.Add(2)
	do Data.Add(3)
	do Data.Add(5)
	do Data.Add(3)
	do Data.Add(4)
	do Data.Add(6)
	do Data.Add(7)
	do Data.Add(6)

	foreach datum(Data)
		do Dbg@Log(datum.ToStr())
	end foreach

	do Dbg@Log("==")



	do @remove(&Data, 3)

	foreach datum(Data)
		do Dbg@Log(datum.ToStr())
	end foreach

	do Dbg@Log("==")

	func lambda(x : int) : bool
		return x%2 = 0
	end func

	do @remove_if(&Data,lambda)

	foreach datum(Data)
		do Dbg@Log(datum.ToStr())
	end foreach




	do Kuin@Stop()
	
end func

Kuinにはテンプレートとかないのでとりあえずint型のみ。
アルゴリズム自体はC++のとたいして変わらないのでそんなに説明はいらないと思う。
おもしろいのはイテレータ(とはKuinではいわないけど、慣れていて使いやすい言葉なので便宜的に)を内部に持っているっぽいということ。
なのでHeadで先頭にイテレータをもってきてそれでNextとかでガリガリ。
Delで要素を削除してイテレータを前にすすめる。

remove_ifのほうはそれにプレディケータをうけとるようにしたような。こちらはたいして説明することないと思う。ただ、つかうときにラムダ式がないので名前付き関数作ってそれを渡すしかない...まあ、適当にスコープをきってあげれば普通につかえるんじゃないかと。

Kuinでポリモーフィズムできるか実験

昨日Kuin1.00がリリースされましたね。
ということで早速使ってみました。

と、その前にKuinってなんぞや?という人もいると思うので軽く説明。
ってか抜粋。

プログラミング言語Kuinは、「HSP並みに作りやすく、C++並みに実用的な言語」というコンセプト
で制作された、究極の言語です。 Kuinの主な特徴について以下に列挙します。
オブジェクト指向でありながら、可能な限りシンプルで解りやすい設計
・言語設計の美しさより、実用面での美しさを重視
・ポインタ、イテレータ、テンプレートなど、ややこしい概念はすべて排除(代替機能を用意)
・動的メモリは自動で解放されるので、解放処理が不要
・豊富な標準ライブラリ(3D描画なども簡単)
・コンパイル速度が爆速
・64bitネイティブ機械語を生成するので、実行速度も速い
・何もプログラムを書かなければ、自動でHello World!!になる

製作者はいわずとしれたくいなちゃん(@b2)

さて、ドキュメントにポリモーフィズムとかそこらへんのこと全然書かれていないので
使えるのかな?とか疑問に思ったので試してみた。
結論から言うと使えて以下の様な感じになる。

class Hoge()
	func method()
		do Dbg@Log("hoge")
		return 
	end func
end class

class Foo(@Hoge)
	+func method()
		do Dbg@Log("foo")
		return 
	end func
end class

func getInstance(id :int) : @Hoge
	if (id = 0)
		return #@Hoge
	else
		return #@Foo
	end if

end func

func Main()
	var a: @Hoge :: @getInstance(0)
	do a.method()
	do a :: @getInstance(1)
	do a.method()
	do Kuin@Stop()
end func

迷った点はグローバルスコープのものはすべて@で修飾しなくちゃいけないということでしょうか?
関数やクラスも@で修飾しないといけません。それさえ気をつければあとはドキュメントにしたがって
直感どおりかけます。
ぱっと見気持ち悪いですがなれるとスラスラかけて良い。
次作るゲームにはKuin使おうと思う。

はてなのハイライトはやくKuinに対応しないかな...

巡検に来ています

こんにちは。いかろです。
一ヶ月更新しないというのもあれなので書く←

実は現在清澄演習林にいます。
学科の巡検で実地の地質図をつくるというもの
基本的に鍵層となる広域に追跡可能なテフラを探しそれから断層などの構造を推定していきます.

と口で言うのは容易なのですが
テフラを同定するの大変です。

ヒルも沢山。



帰ってきたらまた細かく書きます(じゃないと月あと数分で終わってしまう...

Phusion PassengerでAliasで設定できない理由

Redmineで最初Aliasでやろうとしてコケました。なんでだろ?と思ってソースコードを追ってみた記録。

Phusion Passengerの公式サイトを見てもRailsBaseURIで設定、シンボリックリンクを張れと書いてあるのでどうやらPassenger自体の仕様のようです。
どのサイト調べてもこうしろとはかいてあるけどなんで?というのは書いてない...
だれも気にならないんだろうか?それとも常識なんだろうか?...
いずれにせよわからないのはきもちわるいのでソースコードを追ってみることにしました。

Passengerフォルダ内のext/apache2/Configuration.cppに

	AP_INIT_TAKE1("RailsBaseURI",
		(Take1Func) cmd_passenger_base_uri,
		NULL,
		OR_OPTIONS | ACCESS_CONF | RSRC_CONF,
		"Deprecated option.")

というRailsBaseURIを定義していそうな部分を見つけました。
このAP_INIT_TAKE1はマクロで第二引数にディレクティブを処理する関数のポインタが来るようです。
そこで次にcmd_passenger_base_uriの実装を探します。

cmd_passenger_base_uri(cmd_parms *cmd, void *pcfg, const char *arg) {
	DirConfig *config = (DirConfig *) pcfg;
	if (strlen(arg) == 0) {
		return "PassengerBaseURI may not be set to the empty string";
	} else if (arg[0] != '/') {
		return "PassengerBaseURI must start with a slash (/)";
	} else if (strlen(arg) > 1 && arg[strlen(arg) - 1] == '/') {
		return "PassengerBaseURI must not end with a slash (/)";
	} else {
		config->baseURIs.insert(arg);
		return NULL;
	}
}

と定義されていました。これを見てみるとDirConfig構造体のBaseURIsにパラメータを代入しています。
そこでDirConfig構造体の定義を探し見るとBaseURIsはstd::setとして定義されていました。
またコメントに「Per-directory configuration information.」とあるのでディレクトリごとの設定を保持する構造体のようです。
insertしているのでRailsBaseURIが複数回現れた場合は上書きされるのではなく追加されます。

次に実際にどう使われているのか調べてみます。
名前的にDirectoryMapper.hが怪しそうなので眺めているとDirectoryMapperというクラス内のautoDetectメソッド内に

/* Find the base URI for this web application, if any. */
const char *baseURI = findBaseURI();
if (baseURI != NULL) {
	/* We infer that the 'public' directory of the web application
	 * is document root + base URI.
	 */
	publicDir = docRoot + baseURI;
} else {
	/* No base URI directives are applicable for this request. So assume that
	 * the web application's public directory is the document root.
	 */
	publicDir = docRoot;
}

という部分がありました。Railsのpublicディレクトリを決定する動作のようです。
baseURIがnullではない場合

publicDir = docRoot + baseURI;

という処理が実行されます。
baseURIはなにが入っているか調べるためfindBaseURIメソッドの定義を見てみたところ、リクエストを解析してBaseURIの集合の中にマッチするものがあれば
それをchar*にして返すという処理をしていました。
ここでなぜAliasで設定できないかという理由がわかりました。
docRootはおそらくApacheのDocumentRootディレクティブで指定された文字列が入り、baseURIはRailsBaseURIで指定されたディレクトリがはいるのでAliasで設定されていてもpublicDirには影響を及ぼしません。
そのためRailsBaseURIで指定してあげる必要があります。
また、Aliasはリクエストが届いた際に振り分ける機能なためAliasを張ったディレクトリに対してRailsBaseURIを指定しても、
Passengerのほうはあくまで実際のファイルシステム上のフォルダを参照するためうまく働きません。
ということでシンボリックリンクをはってRailsBaseURIで指定してあげないといけません。
ということでした。