【发布时间】:2010-11-26 06:56:36
【问题描述】:
我怎样才能使这段代码工作?
class Meta
@array = [:a,:b]
def self.method_missing(name, *args, &block)
if @array.include? name
self.class.send(:define_method, name) do
do_call(name)
end
else
puts "[#{name.inspect}] is not part of array!"
end
end
def do_call arg
puts "doing call for ['#{arg}'] "
end
end
想法是让Meta.a(在被定义之后)拥有
def a
do_call(a)
end
在它的身体里。但是运行这个之后,我的输出是:
[:do_call] 不是数组的一部分!
更新:现在有点像这样工作:
class Meta
@array = [:a,:b]
def self.do_call arg
puts "doing call for ['#{arg}'] "
end
def self.method_missing(name, *args, &block)
puts "#{name} is missing!"
if @array.include? name
self.class.send(:define_method, name) do
do_call name
end
else
puts "[#{name.inspect}] is not part of array!"
end
end
end
但是,这里是 IRB 会话的摘录:
[~/code] $ irb -r 元
irb(main):001:0> Meta.a
缺少一个!
=> #
irb(main):002:0> Meta.a
正在调用 ['a']
=> 无
irb(main):003:0> c = Meta.new
=> #
irb(main):004:0> c.a
NoMethodError: # 的未定义方法 `a'
from (irb):4irb(main):005:0> Meta.methods
=> ["inspect", "send", "pretty_inspect", "class_eval", "clone", "yaml_tag_read_class", >>"public_methods", "protected_instance_methods", "send" , "private_method_defined?", “相等?”,“冻结”,“do_call”,“yaml_as”,“方法”,“instance_eval”,“to_yaml”,“显示”, “dup”、“object_id”、“包括?”、“private_instance_methods”、“instance_variables”、“扩展”、 “protected_method_defined?”、“const_defined?”、“to_yaml_style”、“instance_of?”、“eql?”、 “名称”、“public_class_method”、“hash”、“id”、“new”、“singleton_methods”、 “yaml_tag_subclasses?”,“pretty_print_cycle”,“污点”,“pretty_print_inspect”,“冻结?”, “instance_variable_get”、“autoload”、“constants”、“kind_of?”、“to_yaml_properties”、“to_a”、 “祖先”,“private_class_method”,“const_missing”,“类型”,“yaml_tag_class_name”, “instance_method”、“”、“instance_methods”、“==”、 “method_missing”、“method_defined?”、“超类”、“>”、“pretty_print”、“===”、 “instance_variable_set”、“const_get”、“is_a?”、“taguri”、“>=”、“respond_to?”、“to_s”、“id”、“nil?”、“untaint”、 "included_modules", "const_set", "a", "method"]
什么给了? 'a' 是一个类方法,它不会传递给新的 Meta 对象 (c)。为什么?
【问题讨论】:
标签: ruby metaprogramming method-missing