Ruby のブロック
Ruby のブロックは実のところ proc {} を引数に渡すのを、その proc が一つの場合に限って簡略化して書けるだけなのだけど (実際はちょっと違うっぽいけど)、これがかなりうまくいってるのがおもしろいなぁ。
- return を書かなくていい
- ブロック (というか評価されないメッセージ) を簡単に渡せる
ってのはすごく重要だなぁ。
class TrueClass
def then
@ret = yield
self
end
def else
self
end
end
class FalseClass
def then
self
end
def else
@ret = yield
self
end
end
(foo == bar).then {
puts "hoge"
}.else {
puts "fuga"
}ふつうに綺麗に書ける。
Boolean.prototype.then = function (fun) {
// this は Object になっているので true になってしまう。
// もとの値をとりだすために valueOf()
if (this.valueOf()) fun();
return this;
};
// else は予約語なのでつかえない
Boolean.prototype.els = function (fun) {
if (this.valueOf()) fun();
return this;
};
("foo" == "bar").then(function () {
print("hoge");
}).els(function () {
print("fuga");
});ぜんぜん綺麗じゃない。
ちなみに Io だと if([pred], [then], [else]) 以外にもうえのと同じことがデフォでできる。(Io では引数は基本的に評価されない。Message オブジェクトとしてメソッドにわたる。ただし仮引数を書いた場合は自動で評価される)
("foo" == "bar") then (
"hoge" println
) else (
"fuga" println
). ではなくスペースをメッセージ送信のくぎりにすることはこういうところで生きてきますね。一見したら構文にしか見えない。(if は then/else の評価されたほうの値をかえすけど、else は nil をかえす。then はもちろん self をかえしている)