我正在使用IronRuby在我的应用程序中执行一些脚本。有没有办法在IronRuby中设置类似于C#对象初始值设定语法的属性?
我有很多需要创建和执行的命令(CLR对象),但大多数命令需要在它们上设置属性,我想避免必须将命令分配给变量,以便我可以设置属性。
有没有办法像C#对象那样做initializer syntax?
我正在使用IronRuby在我的应用程序中执行一些脚本。有没有办法在IronRuby中设置类似于C#对象初始值设定语法的属性?
我有很多需要创建和执行的命令(CLR对象),但大多数命令需要在它们上设置属性,我想避免必须将命令分配给变量,以便我可以设置属性。
有没有办法像C#对象那样做initializer syntax?
构建CLR对象时没有设置属性的内置方式,因为它不是Ruby自身的特性。不过,尽管Python不支持这个,IronPython does support it by allowing named parameters to be supplied to constructors。由于Ruby不支持命名参数,因此我们不希望强制实施一个命名参数模式,不管是作为最后一个参数的Hash
还是针对构造对象的instance_eval
块,或者其他人都想出的东西。这就是说,实现对象初始化器的两种策略都可以在纯Ruby中编写,而IronRuby中没有任何特殊的支持。我将描述上面列出的两个,但可以随意尝试,如果它们不是您正在寻找的语法。
假设下面的CLR类(C#编写):
namespace TestLib {
public class TestObj1 {
public string Prop1 { get; set; }
public string Prop2 { get; set; }
}
}
你可以想象初始化与传递给构造块属性:
testobj = TestObj1.new do
self.prop1 = "Prop1 Value"
self.prop2 = "Prop2 Value"
end
这里是你如何可以覆盖TestObj1.new
方法来支持:
class TestObj1
def self.new(*args, &block)
obj = super(*args)
obj.instance_eval &block
obj
end
end
由于这个a通过eval
来阻止新创建的对象,您可以在该块内执行任何Ruby代码。在Ruby中创建DSL和更自然的API时,这种模式非常流行。
或者,如果你喜欢使用Ruby在方法的参数宽松Hash
语法:
testobj = TestObj1.new :prop1 => "Prop1 value", :prop2 => "Prop2 value"
那么这就是你怎么可以覆盖.new
方法:
class TestObj1
def self.new(*args)
last_arg = args[-1]
if last_arg.kind_of?(Hash)
first_args = args[0..-2]
obj = super(*first_args)
last_arg.each do |prop, val|
obj.send("#{prop}=", val)
end
return obj
end
super(*args)
end
end
的Hash
选项肯定是一个位更复杂,但性能更高一些(因为它避免了eval
),并且是Ruby中暴露命名参数的更常见模式。