[英]Dose self.class.class_eval equal to instance_eval?
我想找出instance_eval和class_eval之間的區別,所以我做了一些工作。在互聯網上搜索后,我發現了一些問題,但是還有另一個我無法理解的問題!當我這樣做時:
class FindMe
def method_missing method, *args, &block
method = method.to_s
self.class.class_eval <<-EOF, __FILE__, __LINE__
def #{method}
puts "I'm an instance method! I'm #{method}"
end
EOF
send method, *args
end
def self.method_missing method, *args, &block
method = method.to_s
instance_eval <<-HERE, __FILE__, __LINE__
def #{method}
puts "I'm a class method! I'm #{method}"
end
HERE
send method, *args
end
end
FindMe.new.hello
FindMe.hello
我懂了
I'm an instance method! I'm hello
I'm a class method! I'm hello
當我將代碼更改為:
class FindMe
def method_missing method, *args, &block
method = method.to_s
self.class.class_eval <<-EOF, __FILE__, __LINE__
def #{method}
puts "I'm an instance method! I'm #{method}"
end
EOF
send method, *args
end
def self.method_missing method, *args, &block
method = method.to_s
self.class.class_eval <<-HERE, __FILE__, __LINE__
def #{method}
puts "I'm a class method! I'm #{method}"
end
HERE
send method, *args
end
end
FindMe.new.hello
FindMe.hello
我得到相同的輸出,任何人都可以告訴發生了什么嗎?
通過class_eval
可以修改類,而instance_eval
則只能修改當前實例。 看:
▶ class A
▷ def ceval
▷ self.class.class_eval "def on_class ; puts 'On Class' ; end"
▷ end
▷ def ieval
▷ self.instance_eval "def on_instance ; puts 'On Instance' ; end"
▷ end
▷ end
▶ a1 = A.new
#⇒ #<A:0xcf6a87c>
▶ a1.ceval
#⇒ :on_class
▶ a1.ieval
#⇒ :on_instance
▶ a1.on_class
#⇒ On Class
▶ a1.on_instance
#⇒ On Instance
▶ a2 = A.new
#⇒ #<A:0xd0e9f7c>
▶ a2.on_class
#⇒ On Class !!! IT IS DEFINED ON NEWLY CREATED INSTANCE OF A
▶ a2.on_instance
#⇒ NoMethodError: undefined method `on_instance' for #<A:0xd0e9f7c>
后者失敗是因為我們在實例a1
上聲明了on_instance
方法,而a2
對此一無所知。
請參見以下示例,並嘗試向自己解釋:
class Foo
def a
self.class.class_eval <<-EOS
def x
'This is an instance method.'
end
EOS
end
def b
self.instance_eval <<-EOS
def y
'This is a singleton method.'
end
EOS
end
end
foo1 = Foo.new
foo2 = Foo.new
foo1.a
foo1.b
foo1.x #=> This is an instance method.
foo1.y #=> This is a singleton method.
foo2.x #=> This is an instance method.
foo2.y #=> NoMethodError
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.