區別:
instance_eval
的接受者為物件,為物件建立了一個單鍵方法
,class_eval接受者為一個類時,定義一個類的例項方法
當物件是類物件時,該方法成為類方法,因為類也是Class的例項
class_eval
我們有個Game類
class Game
attr_accessor :name, :owner
def initialize(name)
@name = name
end
end
使用class_eval
新增例項方法
Game.class_eval do
def hello
puts "helloworld"
end
end
我們定義了一個例項方法hello,列印helloworld出來
irb(main):017:0> Game.new("asdf").hello
helloworld
=> nil
也可以用class_eval
新增類方法,比如對Game類新增find_by_owner
的類方法
程式碼:
Game.class_eval do
def self.find_by_owner(name)
end
end
沒有self,則class_eval新增的是例項方法
instance_eval
使用instance_eval
設定物件的例項屬性
contra_game = Game.new(`Contra`)
設定contra_game
物件的owner例項屬性為Alice
程式碼:
contra_game = Game.new(`Contra`)
contra_game.instance_eval do
@owner = "Alice"
end
如果對Game類使用instance_eval
定義的方法就是Game類的類方法,Game是Class
的例項,Game的單鍵方法
就是Game
的類方法
比如這個例子中,定義find_by_owner
的類方法
irb(main):018:0> Game.instance_eval do
irb(main):019:1* def find_by_owner(name)
irb(main):020:2> puts name
irb(main):021:2> end
irb(main):022:1> end
=> nil
就可以呼叫定義好的類方法了
irb(main):023:0> Game.find_by_owner("who")
who
=> nil
在物件的上下文中執行一個block
使用instance_eval
和block_given?
在Game類的建構函式中實現接受一個可選的block,並呼叫block
class Game
def initialize(&block)
instance_eval(&block) if block_given?
end
def owner(name=nil)
if name
@owner = name
else
@owner
end
end
end
links