看到一片老文章,关于cattr_accessor和class_inheritable_accessor

So, cattr_accessor doesn’t work like it should?

Posted by Dr Nic on August 27, 2006

Rails’ active_support library adds some wonderful functions into standard Ruby classes. Some we all use day-in-day out are attr_accessor and its class-level equivalent, cattr_accessor.

But cattr_accessor doesn’t work the way you (read, “me”) thought at first glance when you use subclasses. I thought if I declared a class accessor in the superclass, then I would have independent class attributes for all my subclasses. Apparently not…

>> class Parent; cattr_accessor :val; end
=> [:val]
>> class Child1 < Parent; end
=> nil
>> class Child2 < Parent; end
=> nil
>> Child1.val = 4
=> 4
>> Child2.val
=> 4
>> Child2.val = 5
=> 5
>> Child1.val
=> 5

Child1.val and Child2.val seem to be the same value. Not very independent at all. Internally, the classes share a common class attribute. This is useful in certain circumstances, but not what I was looking for.

Instead, I found class_inheritable_accessor.

>> class Parent; class_inheritable_accessor :val; end
=> [:val]
>> class Child1 < Parent; end
=> nil
>> class Child2 < Parent; end
=> nil
>> Child1.val = 4
=> 4
>> Child2.val = 4
=> 4
>> Child2.val = 5
=> 5
>> Child1.val
=> 4

Lovely. Each subclass will have an independent value once you’ve assigned it a value explicitly, else it will pick up the value from its superclass.

UPDATE: class_inheritable_accessor and co. actually clone the superclass’s inherited attributes, rather than just referencing them.

你可能感兴趣的:(Ruby,UP,Rails)