ben*_*nbs 5 ruby closures metaprogramming
我有一个ruby程序,我想接受用户的编写方法,并用该名称创建一个新方法.我试过这个:
def method_missing(meth,*args,&block)
name = meth.to_s
class << self
define_method(name) do
puts "hello " + name
end
end
end
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
`define_method': interning empty string (ArgumentError) in 'method_missing'
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?谢谢.
编辑:
我让它以不同的方式工作,但我仍然很好奇如何以这种方式做到这一点.这是我的代码:
def method_missing(meth,*args,&block)
Adder.class_eval do
define_method(meth) do
puts "hello " + meth
end
end
send("#{meth}")
end
Run Code Online (Sandbox Code Playgroud)
Chu*_*uck 12
该变量name在类定义(class << self)范围内不可用.它没有抛出NameError,因为你已经覆盖了method_missing.
要做你想做的事,你需要保持范围name.为了做到这一点,你必须只使用基于块的方法(例如class_eval)而不是直接打开类,所以像这样:
def method_missing(meth,*args,&block)
name = meth.to_s
eigenclass = class << self; self; end
eigenclass.class_eval do
define_method(name) do
puts "hello " + name
end
end
end
Run Code Online (Sandbox Code Playgroud)
但实际上,符号meth就足够了 - 你根本就不需要名字.(尽管你仍然需要上述技术.)最重要的是,你想立即执行该方法.最简单的方法就是重新发送消息:
def method_missing(meth,*args,&block)
eigenclass = class << self; self; end
eigenclass.class_eval do
define_method(meth) do
puts "hello #{meth}"
end
end
send(meth, *args, &block)
end
Run Code Online (Sandbox Code Playgroud)