Ruby in D

演算子オーバーロードを駆使してRubyっぽくかけるようにしよう!というテーマ。酷い。

import std.c.stdio;

struct Each(T){
    T[] ary_;
    Each_!(T) opOr(out T t){
        Each_!(T) e;
        e.ary_ = ary_;
        e.ptr_ = &t;
        return e;
    }
}

struct Each_(T){
    T* ptr_;
    T[] ary_;
    void opOr_r(void delegate() stat){
        foreach (T t; ary_){
            *ptr_ = t;
            stat();
        }
    }
}

Each!(T) each(T)(T t, ...){
    T[] ary;
    ary ~= t;
    for (int i = 0; i < _arguments.length; i++){
        assert(_arguments[i] == typeid(T));
        ary ~= *cast(T*)_argptr;
        _argptr += T.sizeof;
    }
    Each!(T) e;
    e.ary_ = ary;
    return e;
}

void main(){
    int i = 0;
    each(1, 2, 3) |i| printf("%d\n", i);
}

型安全な可変個引数関数はテンプレート関数に出来ないので、eachが酷いことになっています。已む無しか…
問題点は幾つもありますが、一番大きいのは、

each(1, 2, 3) |i| printf("%d\n", i), printf("hoge\n");

などと書いてもopOr_rの引数にはprintf("%d\n", i)しか渡せないことですね…
ただこれは、doとendも使うようにしてやって、

each(1, 2, 3).do_ |i|
    printf("%d\n", i) >>
    printf("hoge\n") >>
end_;

とかしてやれば解決するかなあとか…頭悪いですね。
追記:演算子の評価順がうまくいかないので無理ですね。がっかり!