ifを作ろう!
楽しそうなタイトルです。タイトルだけっぽいです。
import std.c.stdio; struct if_{ bool delegate() cond_; void delegate()[] true_stats_; void delegate()[] false_stats_; bool delegate()[] elsif_conds_; void delegate()[][] elsif_stats_; static if_ opCall(bool delegate() cond){ if_ i; i.cond_ = cond; return i; } if_ then_(void delegate()[] stats ...){ if (elsif_conds_.length > 0){ elsif_stats_ ~= stats; } else { true_stats_ = stats; } return *this; } if_ else_(void delegate()[] stats ...){ false_stats_ = stats; return *this; } if_ else_if_(bool delegate() cond){ elsif_conds_ ~= cond; return *this; } void end_(){ if (cond_()){ foreach (void delegate() stat; true_stats_){ stat(); } return; } if (elsif_conds_.length > 0){ foreach (int i, bool delegate() cond; elsif_conds_){ if (cond()){ foreach (void delegate() stat; elsif_stats_[i]){ stat(); } return; } } } foreach (void delegate() stat; false_stats_){ stat(); } } } void main(){ int x = 0; if_(x == 0).then_( printf("hoge\n") ).else_if_(x == 1).then_( printf("hige\n") ).else_if_(x == 2).then_( printf("huge\n") ).else_( printf("hage\n") ).end_(); }
Rubyっぽいのは趣味、ではなく、else ifも実装するとなると、まあこうなるよなあと思ったからなのでした。
割とあっという間に出来た感じです。明らかに必要のないflag入ってるあたりがそう物語っているというか、酷い。
opCallのcondがtrueだったら、もうthen_より後ろの部分全部無視でいいな、とshinhさんのコードを見て思いました。flagも含めて直そう…
flag直した。
this.いらないといわれて直しました。恥ずかしい…
あと、then_タイプするのめんどくせーと言う場合は、
if_ opCall(void delegate()[] stats ...){ return then_(stats); }
とかして、
if_(x == 0)( printf("hoge\n") ).end();
とか書けるという噂。
then_消すならend_も実に消したいんですが、とりあえず最後にend_呼ばないといけないので何かしらくっつけないといけない…
opSlice()を使うと言う妙案を思いついて実際に試してみたら見栄えが酷くて泣きそうになりました。
あとどうせRubyっぽくするならelsif_にすればいいですね…
次何しようかなあ。