Michael Durrant
Michael Durrant

Reputation: 96484

Use Constant or Class Variable?

I am showing a number of navigation links on a page. It will be fixed in the application but in the future could change, but not interactively, just if a new release changed it. So fixed within the application in use.

The number of links is set for use within many different actions in the controller.

Should I use a class level variable @@number_of_links to make it stay within the class and allow other uses (different controllers and models say) of the same name without conflict (i.e. scoped), or should I use a constant like NumberOfLinks?

I've been given advice on both and would like to confirm my preference for the first.

Upvotes: 1

Views: 2358

Answers (5)

Orlando
Orlando

Reputation: 9692

Like Iain says.. use class instance variables.. but you can reduce that code using attr_accessor

class Foo
  class << self; attr_accessor :number_of_links; end
  self.number_of_links = 10 #default value..
end

puts Foo.number_of_links
# => 10
Foo.number_of_links = 20

puts Foo.number_of_links
# => 20

Upvotes: 2

Jesse Storimer
Jesse Storimer

Reputation: 511

If it will only be changed with a new release of the software then make it a constant. That better reflects the intent of that value.

Values that won't be changed by application logic do not need to be transient variables. I avoid class variables (and class instance variables) when possible because many developers have trouble understanding the difference between the two, when to use them, etc.

Upvotes: 2

ian
ian

Reputation: 12251

It's definitely not a constant unless it's constant!

Instead of a class variable, I'd suggest a class-instance variable. You get all the benefits of a class variable, with even better scoping (other members of the class won't clobber the value, and easier access too.

class Foo

  class << self
    def number_of_links
      @number_of_links ||= 10 # or some sensible default, you might make this a constant to highlight the number when you're reading the code.
    end

    def number_of_links=( n )
      @number_of_links = n
    end
  end
end

puts Foo.number_of_links
# => 10
Foo.number_of_links = 20

puts Foo.number_of_links
# => 20

see http://blog.codegram.com/2011/4/understanding-class-instance-variables-in-ruby for more.

Upvotes: 4

josephrider
josephrider

Reputation: 943

If it is something of a strict nature that you don't plan on modifying with application logic you should use a constant.

If it is something you expect to change with the state of the class (if it is extrapolated based on the state of a database interaction) you should use a class variable.

From a performance perspective it doesn't matter, in this case, using it the way described above you can assume the intent using the type of variable which makes it easier for contributing developers to understand without "decoding".

Upvotes: 1

nhm tanveer
nhm tanveer

Reputation: 682

let's say you need to update number of links if you do it over constant ruby will warn like this "warning: already initialized constant NumOfLinks"

in such case you should stick with class variable.

Upvotes: 0

Related Questions