在 Ruby 中定义元编程的方法参数
Define method parameters for meta programming in Ruby
在Ruby中,我们可以使用元编程定义实例方法,如:
define_method(:hi) { 'Hello, SO world!' } # => :hi
hi # => "Hello, SO world!"
这样,就可以用动态名称定义一个方法:
dynamic_name = :hi # => :hi
define_method(dynamic_name) { 'Hello, SO world!' } # => :hi
hi # => "Hello, SO world!"
我们还可以将参数注入到动态方法中:
dynamic_name = :hi # => :hi
define_method(dynamic_name) do |arg1, arg2, &block|
'Hello, SO world!'
end # => :hi
hi(42, 42) { 42 } # => "Hello, SO world!"
到目前为止,还不错。
但是我们如何才能注入动态参数?
是否可以用动态符号替换 arg1, arg2, &block
?
感谢您提供任何提示、最佳实践甚至想法。
编辑:
换句话说,我也想动态定义实例方法的参数和块。
但是,我想使用特定数量的参数(可能为 0)、一个可选的数组并完成方法块。
这样,我就可以避免使用以下方法:
dynamic_name = :hi # => :hi
define_method(dynamic_name) do |*args, &block|
'f'
end # => :hi
hi # => "f"
hi(:foo) # => "f"
hi(:foo, :fooo) # => "f"
hi(:foo, :fooo, :foooo) # => "f"
...这是废话,因为在这里我们可以给方法无限多的未使用参数。我想避免这种情况。
编辑 2:
原因如下:
在Ruby中,当我们需要一个不需要任何参数的方法时,我们可以简单地做:
def my_method
"Hello, SO world!"
end
但是,如果我这样做:
def my_method(*args)
"Hello, SO world!"
end
...结果还是一样,但是因为参数(数组args
)没用,所以最好把它从方法中去掉来保持简单。
尝试传递数组或字典。
更新:
if condition1
class_eval <<-EVAL
def #{"my_method"}(arg1)
end
EVAL
else
class_eval <<-EVAL
def #{"my_method"}
end
EVAL
end
更新 2:
if condition1
self.instance_eval <<-EVAL
def #{"my_method"}(arg1)
end
EVAL
else
self.instance_eval <<-EVAL
def #{"my_method"}
end
EVAL
end
更新 3:
# or
self.instance_eval("def method1(arg1) puts 'hellowa' + arg1.to_s; end")
self.instance_eval("def method2() puts 'hellowa2'; end")
# and then
method1(33) # => hellowa33
method2 # => hellowa2
在Ruby中,我们可以使用元编程定义实例方法,如:
define_method(:hi) { 'Hello, SO world!' } # => :hi
hi # => "Hello, SO world!"
这样,就可以用动态名称定义一个方法:
dynamic_name = :hi # => :hi
define_method(dynamic_name) { 'Hello, SO world!' } # => :hi
hi # => "Hello, SO world!"
我们还可以将参数注入到动态方法中:
dynamic_name = :hi # => :hi
define_method(dynamic_name) do |arg1, arg2, &block|
'Hello, SO world!'
end # => :hi
hi(42, 42) { 42 } # => "Hello, SO world!"
到目前为止,还不错。
但是我们如何才能注入动态参数?
是否可以用动态符号替换 arg1, arg2, &block
?
感谢您提供任何提示、最佳实践甚至想法。
编辑:
换句话说,我也想动态定义实例方法的参数和块。
但是,我想使用特定数量的参数(可能为 0)、一个可选的数组并完成方法块。
这样,我就可以避免使用以下方法:
dynamic_name = :hi # => :hi
define_method(dynamic_name) do |*args, &block|
'f'
end # => :hi
hi # => "f"
hi(:foo) # => "f"
hi(:foo, :fooo) # => "f"
hi(:foo, :fooo, :foooo) # => "f"
...这是废话,因为在这里我们可以给方法无限多的未使用参数。我想避免这种情况。
编辑 2:
原因如下:
在Ruby中,当我们需要一个不需要任何参数的方法时,我们可以简单地做:
def my_method
"Hello, SO world!"
end
但是,如果我这样做:
def my_method(*args)
"Hello, SO world!"
end
...结果还是一样,但是因为参数(数组args
)没用,所以最好把它从方法中去掉来保持简单。
尝试传递数组或字典。
更新:
if condition1
class_eval <<-EVAL
def #{"my_method"}(arg1)
end
EVAL
else
class_eval <<-EVAL
def #{"my_method"}
end
EVAL
end
更新 2:
if condition1
self.instance_eval <<-EVAL
def #{"my_method"}(arg1)
end
EVAL
else
self.instance_eval <<-EVAL
def #{"my_method"}
end
EVAL
end
更新 3:
# or
self.instance_eval("def method1(arg1) puts 'hellowa' + arg1.to_s; end")
self.instance_eval("def method2() puts 'hellowa2'; end")
# and then
method1(33) # => hellowa33
method2 # => hellowa2