如何让这段代码有效?关于define_method和method_missing的问题
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] is not part of array!
UPDATE:现在还挺工作是这样的:
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 meta
irb(main):001:0> Meta.a
a is missing!
=> #
irb(main):002:0> Meta.a
doing call for ['a']
=> nil
irb(main):003:0> c = Meta.new
=> #
irb(main):004:0> c.a
NoMethodError: undefined method `a' for #
from (irb):4
irb(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?", "equal?", "freeze", "do_call", "yaml_as", "methods", "instance_eval", "to_yaml", "display", "dup", "object_id", "include?", "private_instance_methods", "instance_variables", "extend", "protected_method_defined?", "const_defined?", "to_yaml_style", "instance_of?", "eql?", "name", "public_class_method", "hash", "id", "new", "singleton_methods", "yaml_tag_subclasses?", "pretty_print_cycle", "taint", "pretty_print_inspect", "frozen?", "instance_variable_get", "autoload", "constants", "kind_of?", "to_yaml_properties", "to_a", "ancestors", "private_class_method", "const_missing", "type", "yaml_tag_class_name", "instance_method", "<", "protected_methods", "<=>", "instance_methods", "==", "method_missing", "method_defined?", "superclass", ">", "pretty_print", "===", "instance_variable_set", "const_get", "is_a?", "taguri", ">=", "respond_to?", "to_s", "<=", "module_eval", "class_variables", "allocate", "class", "taguri=", "pretty_print_instance_variables", "tainted?", "public_instance_methods", "=~", "private_methods", "public_method_defined?", "autoload?", "id", "nil?", "untaint", "included_modules", "const_set", "a", "method"]
是什么赋予了? 'a'是一个类方法,它不会传递给新的Meta对象(c)。为什么?
此方法的一个重要警告是method_missing厄运问题的无限循环 –
现在仍然像这样工作...:| –
完成我提到的更改后,它对我来说工作正常。 http://pastie.org/609427 – sepp2k