我正在尝试为Rails ActionDispatch路由器创建一个类似的路由器,它允许您定义类似的路由
map.get "/foo", :controller => "Foo", :action => "index"
然后将路由GET /foo
到FooController#index
.有了这个结构,你可以使用像
map.resources :foos
这将调用像
map.get "/foo", :controller => "Foo", :action => "index" map.get "/foo/:id", :controller => "Foo", :action => "show"
等等.
在D中,我已经能够找出使这项工作所需的许多反身代码,但不是全部.在Ruby中我可以做到:
class Foo def bar "FOOO BAR!" end end f = Object.const_get("Foo") f.new.__send__(:bar) #=> "FOOO BAR!"
我试图翻译成
module foo; import std.stdio; class Foo { void bar() { writeln("FOO BAR!"); } } void main() { auto foo = Object.factory("foo.Foo"); __traits(getMember, foo, "bar"); }
但这不起作用,因为编译器不知道什么类型foo
,所以#bar
在编译期间调用失败.我见过的所有地方都Object.factory
将它们投射到特定类型,所以
module foo; import std.stdio; class Foo { void bar() { writeln("FOO BAR!"); } } void main() { auto foo = cast(Foo) Object.factory("foo.Foo"); __traits(getMember, foo, "bar"); }
会工作得很好.但是,如果我知道我想把对象强加给什么好用的东西Object.factory
?这对我没有任何意义!
更新2我已修复编译器问题,但现在它在运行时崩溃,说它无法找到该方法
module foo; import std.stdio; class MyDynamic { void call(C, T...)(C instance, string method, T args) { foreach(member; __traits(allMembers, C)) { writeln(member); if (member == method) { static if (__traits(compiles, __traits(getMember, instance, member)(args))) { __traits(getMember, instance, member)(args); } return; } } assert(0, "No method found"); } } class Foo : MyDynamic { void bar() { writeln("FOO BAR!"); } } void main() { auto foo = cast(MyDynamic) Object.factory("foo.Foo"); assert(foo !is null); foo.call(foo, "bar"); }
更新对于现在遇到此问题的任何人,您可以在此处查看我的最终解决方案:https://github.com/jaredonline/action-pack