Created
April 14, 2010 21:37
-
-
Save ihower/366372 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Dragon; end | |
# 使用 def 定義 class method | |
Dragon.instance_eval do | |
def foo | |
puts "bar" | |
end | |
end | |
Dragon.foo # bar | |
# 使用 def 定義 instance method | |
Dragon.class_eval do | |
def foo | |
puts "bar" | |
end | |
end | |
Dragon.new.foo # bar | |
# 使用 self.def 定義 class method | |
Dragon.class_eval do # 這裡改用 instance_eval 也可以耶(why?) | |
def self.foo | |
puts "bar" | |
end | |
end | |
Dragon.foo # bar | |
# ------------------------------------------------------------------------------------ | |
# 使用 define_method 定義 instance method | |
class Dragon | |
define_method("foo") { puts "bar" } | |
end | |
Dragon.new.foo # bar | |
Dragon.class_eval do | |
define_method("foo") { puts "bar" } | |
end | |
Dragon.new.foo # bar | |
# 使用 define_method 定義 class method | |
class Dragon | |
class << self | |
define_method("foo") { puts "bar" } | |
end | |
end | |
Dragon.foo # bar | |
# 使用 define_method 嘗試定義 class method | |
Dragon.instance_eval do | |
define_method("foo2") { puts "bar" } | |
end | |
Dragon.foo2 rescue puts "fails" # 失敗找不到 method (why?) | |
# 使用 define_method 定義 class method | |
metaclass = (class << Dragon; self; end) | |
metaclass.instance_eval do # 這裡改用 class_eval 也可以耶(why?) | |
define_method("foo") { puts "bar" } | |
end | |
Dragon.foo # bar | |
# 使用 define_method 定義 class method (不用 metaclass 的話,只好定義在 Class 上) | |
Dragon.class.instance_eval do # 這裡用 class_eval 也可以 | |
define_method("foo") { puts "bar" } | |
end | |
Dragon.foo # bar | |
String.foo # bar,所有類別都被污染啦!! bad idea!! | |
# ------------------------------------------------------------------------------------ | |
# Recommended reading: | |
# | |
# http://yehudakatz.com/2009/11/15/metaprogramming-in-ruby-its-all-about-the-self/ | |
# http://yugui.jp/articles/846 | |
# | |
# My conclusion: | |
# mechanism self(current object) method definition(current class) new scope? | |
# class Dragon Dragon Dragon yes | |
# class << Dragon Dragon’s metaclass Dragon’s metaclass yes | |
# Dragon.class_eval Dragon Dragon no | |
# Dragon.instance_eval Dragon Dragon’s metaclass no | |
# "def method_name" define instance method for current class | |
# "define_method" defind instance method for self (must be class object) | |
# "def object.method_name" defines instance method for object's metaclass (a.k.a singleton method) | |
# New scope means that code inside the block does not have access to local variables outside of the block. | |
# class_eval, instance_eval 和 define_method 這幾個 method 不會有新的 scope 是 Ruby 跑 dynamic code 的利器,因為可以很方便讀取到 block 外的 local variable。 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment