Justin
Justin

Reputation: 51

Ruby instance variables and methods

Sometimes I see an instance variable defined as @my_variable. However, sometimes I see self.my_variable. When is each used?

Upvotes: 5

Views: 4561

Answers (3)

hammar
hammar

Reputation: 139920

Instance variables (@variable) correspond to private variables in other languages. self.myvariable is actually not a variable, but a call to a method. Similarly, if you write self.myvariable = something, it is actually a call to self.myvariable=(something). This corresponds to properties with getters and setters in other languages.

class Foo
  def initialize
    @bar = 42
  end

  def xyzzy
    123
  end

  def xyzzy=(value)
    puts "xyzzy set to #{value}!"
  end
end

obj = Foo.new
puts obj.xyzzy # prints: 123
obj.xyzzy = 2  # prints: xyzzy set to 2
puts obj.bar   # error: undefined method 'bar'

You can use attr_reader and attr_accessor to automatically define getters and setters for an instance variable. attr_reader will only generate a getter, while attr_accessor generates both.

class Parrot
  attr_accessor :volts

  def voom
    puts "vooming at #{@volts} volts!"
  end
end

polly = Parrot.new
polly.volts = 4000
polly.voom   

Upvotes: 12

sawa
sawa

Reputation: 168239

Instance variables are more primary things than methods calling them. In self.myVariable, myVariable is a method referring to the instance variable @myVariable, and that method is defined usually by attr_reader or attr_accessor.

One purpose of object orientated programming is to encapsule things particular to an instance inside that instance and make it inaccessible from outside of it. This way, you can avoid unwanted conflicts of name. This is true for instance variables. They are usually parameters to be handeled within the instance, and not to be used outside of it.

Within an instance, its instance variables can be directly referred to, and hence there is no need to refer to them via method calls. You should directly call the variable @myVariable.

From outside of an instance, you cannot directly refer to the instance variables because of the reason mentioned above. But sometimes, you do need to refer to them. The purpose of using the method myVariable is to refer to the instance variable from outside of an instance.

Upvotes: 1

dnch
dnch

Reputation: 9605

@my_variable refers directly to the instance variable, and is (for the most part) inaccessible from outside that instance.

self.my_variable is using an accessor method (as defined with attr_reader, attr_writer or attr_accessor internally. This is in cases where there may not be an instance variable named @my_variable (as is the case with ActiveRecord model attributes) or where the internal state differs from what is exposed publicly.

Upvotes: 0

Related Questions