我试图创建一个类似路由器的Rails ActionDispatch路由器,它允许您定义使用Object.factory无需强制转换为特定类型
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
虽然,目前我D是segfaulting,我不知道为什么。 – jaredonline
“现在它在运行时崩溃,说它找不到方法”,这是因为你的上下文中的'C'被推断为'MyDynamic',而不是'Foo'。没有某种'ClassInfo'帮助进行运行时反射是不可能的。 –
什么样的'ClassInfo'帮助? – jaredonline