Neil
Neil

Reputation: 5178

How to access instance variable defined within class << self

Given the following code, how come Dog.speak does not return "here is the @var variable":

class Dog
  class << self
    @var = "here is the @var variable"

    def speak
      @var
    end
  end
end

p Dog.speak

Instead it returns nil

My understanding: class << self opens up the singleton class object of Dog. On that singleton object, we are setting the instance variable of @var. Thus, I would think that the instance variable of @var is accessible from Dog.speak.

What concepts am I missing here? Why is @var not accessible to the speak method?

Confusingly, this however works as expected:

class Dog
  class << self
    def set_it
      @var = "The instance variable of @var is now accessible"
    end

    def speak
      @var
    end
  end
end

Dog.set_it
p Dog.speak # => "The instance variable of @var is now accessible"

Upvotes: 2

Views: 76

Answers (2)

Sergio Tulentsev
Sergio Tulentsev

Reputation: 230286

how come Dog.speak does not return "here is the @var variable"

For the very same reason why this behaves similarly:

class Dog
  @var = "here is the @var variable"

  def speak
    @var
  end
end

Dog.new.speak # => nil

You set variable on class level and expect it to be available on instance level.

Upvotes: 2

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 121000

You declare the variable on singleton class level and try to access it on class level. Debug output is your friend:

class Dog
  class << self
    puts "I am #{self}"
    @var = "here is the @var variable"

    def speak
      puts "I am #{self}"
      @var
    end
  end
end

Prints out:

#⇒ I am #<Class:Dog>
▶ Dog.speak
#⇒ I am Dog

Note, that the former is printed while the code is parsed and the latter is printed only when the call to Dog.speak is explicitly performed.

Upvotes: 4

Related Questions