Private Member Variables in Ruby

If you’re new to Ruby, especially if you’re coming from a Rails background, you probably use attr_accessor (if not outright adding columns to the table in Rails) to add member variables to a class. Like so:


class Player
attr_accessor :x, :y
end

What does this mean? It means you can do things like:


p = Player.new
p.x = 2;
p.y += 3;
puts "Player is at (#{p.x}, #{p.y})."

i.e. you get the ability to both read and write to x and y, for FREE–without any additional code. Smooth!

But, if you’re like me, you will probably reach a point where you want to add some member variables, but not make them publically accessible. How do you do it?

The answer is to use the @name convention, like so:


class Player
def initialize(x, y)
@x = x
@y = y
end
end

Unlike the attr_accessor code above, this does NOT allow you to do things like:


p = Player.new(3, 4)
puts "Player is at #{p.x}, #{p.y}" # raises an error: X and Y don't exist

But, as I mentioned, that’s what this is for–creating private member variables.

Also, realize that in Ruby, objects are very dynamic–you can add properties on the fly! We didn’t explicitly “declare” x and y anywhere in our Player class; yet we can access them.

And that, in a nutshell, is private member variables. One last thing to note–you can almost think of attr_accessor :some_thing as equivalent to:


class Whatever
@some_thing = nil

def some_thing
return @some_thing
end
def some_thing=(value)
@some_thing = value
end
end

But of course, all this is free by using attr_accessor. So use it!

About Ashiq Alibhai

Ashiq Alibhai, PMP, has been a Rails aficionado since 2007, and developed web applications since early 2003, where he learned PHP in one summer. As the driving-force behind RailsRocket and the Launchpad project, he seeks to share the ease of development with Rails far and wide.
This entry was posted in Development and tagged , , , . Bookmark the permalink.

One Response to Private Member Variables in Ruby

  1. Wayne Conrad says:

    You can make private accessors by putting the attr_… helper inside the private section of the class:

    #!/usr/bin/ruby1.8

    class Foo

    def set_baz
    self.baz = 2
    end

    def show_baz
    puts “baz = #{baz}”
    end

    private

    attr_accessor :baz

    end

    foo = Foo.new
    foo.set_baz
    foo.show_baz # prints ’2′
    p foo.baz # Fails: “private method ‘baz’ called”