我有一些像
这样的课程class Demo1 < Struct.new(:text, :text2)
end
class Demo2 < Struct.new(:text, :text2, :text3)
end
如果我只有名称和参数哈希,我如何调用每个类的构造函数 我需要写这样的方法, 但这是错误的,因为发送后(:new,args)Struct将包含:等于args的文本
def call_demo_object(demo_name, args={})
demo_name.to_s.constantize.send(:new,args)
end
mian问题是使用hash
中的随机参数调用构造函数答案 0 :(得分:3)
变体一:
def call_demo_object(demo_name, args={})
z = [':new']
args.keys.each do |key|
z.push "args[:"+key.to_s+"]"
end
eval('demo_name.to_s.constantize.send(' + z.join(', ') +')' )
end
变体二:
def call_demo_object(demo_name, args={})
a = demo_name.to_s.constantize.send(:new)
args.each do |key, value|
a[key] = value if a.members.include?(key)
end
a
end
答案 1 :(得分:2)
一种可能的变体:
def call_demo_object(demo_name, args={})
obj = demo_name.new
obj.members.each do |member|
obj[member] = args[member]
end
obj
end
这是优点:
args
可以按任何顺序答案 2 :(得分:1)
我看到了一些错误:
不确定您的课程是否真的如此,但您最后需要end
,否则会出现语法错误。
另外,constantize
不是Ruby中字符串的方法,而是Rails定义的方法。所以你需要使用
Kernel.const_get(demo_name.to_s)
获得相同的功能。
正如评论中所指出的,我忽略了如何扩展参数。
要做到这一点,你需要使用所谓的“splat operator”
Kernel.const_get(demo_name.to_s).send(:new,*args) #notice the * in front of args
这将扩大args。
然而,当args是一个哈希值时,比如说{:text=>"hello", :text2=>"hello2"}
,它会将它扩展为一个包含2个元素的数组,其中每个元素都是一个数组,它们键在第一个位置,键在第二个位置。< / p>
相反,如果您按顺序将对象传递给args
,那么您将获得所需的内容。
我认为,如果您要使用的是命名参数,您可能需要尝试其他路线,但我肯定不知道。
要使用可选参数或命名参数,您可以查看Rails如何执行此操作:对参数使用哈希,然后使用键传入哈希。然后,您可以保留有效的密钥列表并检查传入的哈希,并拒绝它们或引发错误。