이 코드는 어떻게 작동합니까?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
아이디어는 본문
def a
do_call(a)
end
을 갖는 (이후에 정의되는) Meta.a을 가지고있다. 그러나이 프로그램을 실행 한 후, 내 출력은 다음과 같습니다
[: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)로 전달되지 않습니다. 왜?
또한이 접근법의 큰 경고는 doy 문제 –
의 무한 루프를 method_missing하여 지금도 이와 같이 작동하고 있습니다. –
내가 언급 한 변경을 한 후에, 그것은 나에게 잘 작동한다. http://pastie.org/609427 – sepp2k