ruby > thoughts.find_all(&:sfw?).to_blog
 => #<URI::HTTP:0x00001 URL: http://MichaelXavier.net >
ruby > MichaelXavier.info
 =>  [ GitHub , Resume , Email ]
ruby > _

What you don't know about cattr_accessor can kill you
01|09|2010 — 0 comments  

Categories: ruby, rails, tips

cattr_accessor is a convenience method added via ActiveSupport as I recall. It works much in the same way of attr_accessor and comes in the form of writer and reader as well. Unfortunately, this convenience led me to assume that cattr_accessor is to inheritance what attr_accessor is to individual instances of a class. In other words, I figured that changing a class variable in a subclass would change it only for that subclass. Such is not the case.

Consider the following example:


            class Fruit
              @@delicious = true
              cattr_reader :delicious
            end
            
            puts "Fruit is delicious: #{Fruit.delicious}"          #Prints true
            
            #HoneyDew is gross
            class HoneyDew < Fruit
              @@delicious = false
            end
            
            #One would think this would inherit the class variable. One would be wrong.
            class Banana < Fruit
            end
            
            puts "Fruit is delicious: #{Fruit.delicious}"         #Prints false 
            puts "HoneyDews are delicious: #{HoneyDew.delicious}" #Prints false 
            puts "Bananas are delicious: #{Banana.delicious}"     #Prints false  
            

You will notice that the class variable is shared and that it is modified in the order that the code is evaluated. I made a bad decision to use code like this in an application I was writing and it caused some very unexpected behaviour.

I would suggest just defining class methods and leave out the class variables entirely. On writers, this allows you some control and error checking for potentially undesirable input and is overall a more forward, if not slightly more verbose approach.

Comments Comments RSS Feed

Add Comment

(required)
(required, won't be displayed)

(Use Markdown syntax)