我正在尝试使用此代码以通用方式排列各种函数:
{ Object.const_get(object_name).new(job[:params]||={}).delay(:queue => queue).send(method_name)}
job
是一个哈希,我得到名称,对象参数等......
我遇到的问题是:
class Foo
def initialize
puts 'bar'
end
end
Foo
不会为其实例提供参数。
因此,如果我使用前一行Foo
作为object_name
,我会收到此错误:
ArgumentError: wrong number pf arguments (1 for 0)
我绝对不想写那样的东西:
if job.has_key?[:param] then
Object.const_get(object_name).new(job[:params]||={}).delay(:queue => queue).send(method_name)
else
Object.const_get(object_name).new().delay(:queue => queue).send(method_name)
end
我可以写什么而不是job[:params]||={}
所以它适用于每个案例?
提前致谢。
答案 0 :(得分:1)
initialize
类的Foo
方法应该接收带有默认值的参数。像这样:
class Foo
def initialize(params={})
# Here you do stuff like checking if params is empty or whatever.
end
end
这样你就可以实现这两种行为。
答案 1 :(得分:1)
您可以使用Foo.send并使用数组来实现此目的。
例如
Object.
const_get(object_name).
send(*(job.has_key?(:param) ? ['new', job[:param]] : ['new']))...
我个人认为这不值得,而if
声明在眼睛上更容易。
答案 2 :(得分:0)
根据您的示例,我认为您接受的测试可能是错误的。您的代码建议您不应该测试散列中是否存在:params键,您应该测试initialize是否接受参数。如果initialize确实接受了一个参数,那么无论是否存在:params键,你都会发送一个参数。当hash中没有:params键时,接受的答案将失败,但是initialize方法接受一个参数 - 你会得到0表示1个错误。这有可能吗?
class Dog
def initialize(params)
p params
puts "dog"
end
end
class Cat
def initialize
puts "cat"
end
end
class_names = ["Dog", "Cat"]
job = {
params: {a: 1, b: 2, c: 3}
}
class_names.each do |class_name|
class_obj = Object.const_get(class_name)
if class_obj.instance_method(:initialize).arity == 0
send_args = 'new'
else
send_args = 'new', job[:params] ||= {}
end
class_obj.send(*send_args)
end
--output:--
{:a=>1, :b=>2, :c=>3}
dog
cat