では無いけど、こんなもん書いてみるテスト。
この規則で書くとFirefoxの拡張(Javascript)に良く使われてる関数乗っ取りが可能になるという長所が。但し、速度が遅くなるけど。
プロトタイプ未実装。キャストとか関数呼び出しとかが面倒なのはvariant.d側の問題。objectという名前が既にvariant.dで使われてたのでobjにした。あと連想配列のバグのせいでキーの文字が一文字しか使えない…。
import std.stdio, std.variant; alias Variant var; alias var[string] obj; alias var delegate(var[]...) func; obj o; static this(){ o = [ "i"[]:cast(var)10, "f":cast(var)(var[] args...){return o["i"];} ]; } void main(){ writefln(o["i"]); writefln(o["f"].get!(func)()()); }
プロトタイプ対応途中。std.variantの実装に問題あるので一時中断。
std.variantをフォークするのが楽そう。
import std.conv, std.stdio, std.variant; alias Variant var; private var[string] objinit = ([ /// function new(_this); "new"[]:cast(var)(var[] args...){ var[string] rv; var[string] _this = args[0].get!(var[string])(); if(_this["prototype"].get!(var[string])()["prototype"] != objinit) rv = _this["prototype"].get!(var[string])()["prototype"].get!(var[string])()["new"].get!(func)()(_this).get!(var[string])(); foreach(string key,var val;_this["prototype"].get!(var[string])) rv[key]=val; if(!("this" in rv)) rv["this"]=cast(var)_this; return cast(var)rv; }, "prototype":cast(var)objinit ]); typedef var[string] obj = objinit; alias var delegate(var[]...) func; obj o, _o; static this(){ _o["prototype"] = [ "i"[]:cast(var)10, "f":cast(var)(var[] args...){return o["i"];} ]; obj o; o = _o.get!(var[string])()["new"].get!(func)()(o); } void main(){ writefln(o["i"]); writefln(o["f"].get!(func)()()); }