![](/img/trans.png)
[英]how to give attr_accessor to all the instance variables in class ruby
[英]Ruby instance_eval on a class with attr_accessor
我理解instance_eval
和class_eval
之間的基本區別。 我在玩游戲時發現的東西是涉及到attr_accessor
奇怪之attr_accessor
。 這是一個例子:
A = Class.new
A.class_eval{ attr_accessor :x }
a = A.new
a.x = "x"
a.x
=> "x" # ... expected
A.instance_eval{ attr_accessor :y }
A.y = "y"
=> NoMethodError: undefined method `y=' for A:Class
a.y = "y"
=> "y" # WHATTT?
怎么樣:
首先,你的理解(或直覺)是正確的, #instance_eval
和#class_eval
中定義的方法是不一樣的
A = Class.new
A.instance_eval { def defined_in_instance_eval; :instance_eval; end }
A.class_eval { def defined_in_class_eval; :class_eval; end }
A.new.defined_in_class_eval # => :class_eval
A.defined_in_instance_eval # => :instance_eval
一個側面說明:雖然self
是在兩個相同的instance_eval
和class_eval
, 默認definee不同的是,看到http://yugui.jp/articles/846
真正的訣竅是Module#attr_accessor
本身,看看它的定義: http : Module#attr_accessor
它不使用def
,它不讀取上下文, self
或默認的definee。 它只是“手動”將方法插入到模塊中。 這就是結果違反直覺的原因。
有關class_eval
和instance_eval
之間的區別,請參閱動態創建類方法
class A; end
A.class_eval do
attr_accessor :x
def barx; end
define_method :foox do; end
end
print 'A.instance_methods : '; p A.instance_methods(false).sort
print 'A.singleton_methods : '; p A.singleton_methods
class B; end
B.instance_eval do
attr_accessor :y
def bary; end
define_method :fooy do; end
end
print 'B.instance_methods : '; p B.instance_methods(false).sort
print 'B.singleton_methods : '; p B.singleton_methods
class C; end
singleton_class = class << C; self end
singleton_class.instance_eval do
attr_accessor :z
def barz; puts 'where is barz ?' end
define_method :fooz do; end
end
print 'C.instance_methods : '; p C.instance_methods(false).sort
print 'C.singleton_methods : '; p C.singleton_methods
print 'singleton_class.barz : '; singleton_class.barz
print 'singleton_class.methods : '; p singleton_class.methods(false)
輸出(紅寶石1.8.6):
A.instance_methods : ["barx", "foox", "x", "x="]
A.singleton_methods : []
B.instance_methods : ["fooy", "y", "y="]
B.singleton_methods : ["bary"]
C.instance_methods : []
C.singleton_methods : ["z", "z=", "fooz"]
singleton_class.barz : where is barz ?
singleton_class.methods : ["barz"]
正如您在B中看到的那樣,盡管instance_eval通常會創建單例方法,但顯然attr_accessor
和define_method
強制實例方法的定義。
A.singleton_class.class_eval { attr_accessor :y }
A.y = 'y'
A.y
方法attr_accessor
是一個類方法,當在類的主體中調用時,然后在該類的實例上定義訪問器方法。
當你執行A.class_eval{...}
,你在類 A
的主體內調用它,因此它的實例 (如a
被分配了訪問器。
當您執行A.instance_eval{...}
,您在A
類的非主體內調用它,因此其實例未分配訪問者。
如果你做Class.class_eval{attr_accessor :z}
,那么你用類 Class
的主體調用它,所以它的實例如A
將被賦予訪問器: Az = ...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.