Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby: Instance variables vs local variables

Tags:

ruby

I'm learning Ruby right now, and I'm confused as to why I can refer to an instance variable without the @ sigil, which would make it a local variable too. Surely the following code shouldn't work as it does:

class Test
  attr_accessor :variable
  def something
    variable
  end
  def something2
    @variable
  end
  def something3
    self.variable
  end
end

y = Test.new
y.variable = 10
puts y.something  # => 10
puts y.something2 # => 10
puts y.something3 # => 10

I'd have expected y.something to return nil. Why do local variables and instance variables point to the same location? I'd have expected @variable and variable to have been two discrete variables.

like image 866
Matty Avatar asked May 25 '11 09:05

Matty


People also ask

What is an instance variable in Ruby?

What's an instance variable? In the Ruby programming language, an instance variable is a type of variable which starts with an @ symbol. Example: @fruit. An instance variable is used as part of Object-Oriented Programming (OOP) to give objects their own private space to store data.

Are instance variables inherited in Ruby?

Instance variables are not inherited.

Can Ruby modules have instance variables?

It is well known that Ruby has instance and class variables, just like any Object-Oriented language. They are both widely used, and you can recognize them by the @a and @@a notation respectively.


1 Answers

In the code you posted, variable is not a local variable. It is a method call to the instance method named variable, which was defined by:

attr_accessor :variable

This is a shorthand for the following method definitions:

def variable
  @variable
end

def variable=(value)
  @variable = value
end

Note that Ruby does not require parentheses () for a method call, so distinguishing between a local variable and a method is not always easy.

Compare your code with:

class Test
  attr_accessor :foo

  def example1
    foo = nil  # 'foo' is now a local variable
    foo
  end

  def example2
    foo        # 'foo' is a method call
  end
end

x = Test.new
x.foo = 10
x.example1  # => nil
x.example2  # => 10
like image 190
molf Avatar answered Nov 09 '22 01:11

molf