what is "cattr_accessor" (used in acts_as_audited)

Hi Greg,

Had a quick look at this (e.g. cattr_reader - extract below) - still I little unclear to me. Do you think you could run what “cattr_accessor” does in layman’s terms at all? e.g. difference between class & instant aspects. (sorry - the penny hasn’t dropped yet :slight_smile: )

class Songs

@@play_count = 0

def  self.play_count
    # The cattr_reader thang
     @@play_count
end

def play
    @@play_count += 1
end

end

song1 = Songs.new song1.play

1 song2 = Songs.new song2.play 2 Songs.play_count 2

Hope that helps.

thanks Ian - I think I got it - just have to go back and make sense of this within the code that was also doing multiple modules / includes / and extends :slight_smile:

Hi --

Had a quick look at this (e.g. cattr_reader - extract below) - still I little unclear to me. Do you think you could run what "cattr_accessor" does in layman's terms at all? e.g. difference between class & instant aspects. (sorry - the penny hasn't dropped yet :slight_smile: )

In layman's terms, I'd describe it as, "A computer programming thing" :slight_smile: But here's a somewhat super-layman explanation.

Ruby has an attr_* family of methods:

   class C      attr_accessor :x      attr_reader :y      attr_writer :z    end

These attr_* methods are meta-methods; that is, calling them actually results in the automatic creation of other methods. In the example above, instances of C will have the following methods:

   x # reader    x= # writer    y # reader    z= # writer

The idea is to provide a convenient way to get and/or set state in an object:

   c = C.new    c.x = 1 # actually a call to the x= method!    puts c.x # a call to the x method

The way this works is that the reader and writer methods (x, x=, etc.) store/retrieve values in/from instance variables. If you wrote them out, the methods that the attr_* methods create for you would look like this:

   class C      def x # read "attribute" (i.e., value of instance variable)        @x      end

     def x=(value) # set "attribute" (i.e., set instance variable)        @x = value      end

     def y        @y      end

     def z=(value)        @z = value      end    end

In addition to instance variables, Ruby has class variables. The purpose of the cattr_* methods is to provide a mechanism exactly like the above -- but using class variables instead of instance variables. Furthermore, the set/get operations are available both to instances of the class, and to the class itself:

   class D      cattr_accessor :a    end

   d = D.new    d.a = 1 # set via an instance    puts D.a # get via the class

So it's just a kind of elaboration of the original Ruby attribute implementation. To get both the class and its instances to know about the get and set methods, there have to be two of each. So this is what the expanded version of the last example looks like:

   class D      def self.a # class get method        @@a      end

     def self.a=(value) # class set method        @@a = value      end

     def a # instance get method        @@a      end

     def a=(value) # instance set method        @@a = value      end    end

I personally consider "cattr" (class attribute) a misnomer. "Attribute" suggests a property of an object. Class variables do not map onto the state of any particular object; they are visible to a given class, all of its subclasses, and all of the instances of itself and those subclasses. So when you save a value in a class variable, it's a considerable stretch to refer to it as an "attribute". But anyway, the above is how it works and what it does.

David

Yes, it is only in Rails. /activesupport/lib/active_support/core_ext/class/ attribute_accessors.rb

It is set as "nodoc" though, so the definitions don't show up in the API. (Any reason not to change that?)

Kevin