29

如果我有一個attr_accessor類,它默認創建一個實例變量以及相應的getter和setter。但是,不是創建一個實例變量,有沒有辦法讓它創建一個類變量或類實例變量呢?Ruby的attr_accessor如何生成類變量或類實例變量而不是實例變量?

+0

通過「[Seeing Metaclasses Clearly]」(http://viewsourcecode.org/why/hacking/seeingMetaclassesClearly.html)工作「;」當試圖理解Ruby的類和對象的工作方式時非常有幫助。 – 2009-05-22 06:48:19

回答

46

像這樣:

class TYourClass 
    class << self 
    attr_accessor :class_instance_variable 
    end 
end 

你可以看一下這是開元類的類(其中的類本身就是一個實例),並添加屬性給它。

attr_accessor是類Class的方法,它向類中添加了兩個方法,一個讀取實例變量,另一個讀取實例變量,另一個方法設置它。這裏是一個可能的實現:

class Class 
    def my_attr_accessor(name) 
    define_method name do 
     instance_variable_get "@#{name}" 
    end 
    define_method "#{name}=" do |new_val| 
     instance_variable_set "@#{name}", new_val 
    end 
    end 
end 

完全未經測試的類屬性訪問器:

class Class 
    def class_attr_accessor(name) 
    define_method name do 
     class_variable_get "@@#{name}" 
    end 
    define_method "#{name}=" do |new_val| 
     class_variable_set "@@#{name}", new_val 
    end 
    end 
end 
+0

謝謝。我喜歡你的表達方式,它打開了類的元類,並添加了一個附錄。但是爲什麼它會產生一個類實例變量而不是一個類變量?並且是否有可能讓它產生一個類變量,或者這個語法是否僅適用於類實例變量? – 2009-05-21 23:28:21

+0

我不同意,再次查看答案 – 2009-05-21 23:36:57

20

在Rails中(或任何你做require 'active_support'),可以使用cattr_accessor :name來獲得真正的類變量的訪問器。

其他人指出的類實例變量通常更有用。 APIdock cattr_accessor page有一些有用的討論,說明您何時不需要其他人,以及cattr_accessorcattr_readercattr_writer函數的來源。