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

I found myself bitten by my misunderstanding of how class variables worked and found the actual functionality to be somewhat unexpected.

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)