assaf
assaf

Reputation: 67

Why can't I puts an instance variable of a Ruby class if it contains the value of a variable in a module?

When I try to run this code, nothing or nil shows up. I can't seem to understand why, since I thought classes that include modules can access its instance/class variables. I can print out the value just fine if I don't use garbtest and just use the garb= method to assign it a different value. It works fine without assigning it another value since I initialized it to 16 too. Is there something about the instance/class variables in the module Test that makes it equal to nil? Furthermore, when I try to assign garb to @myg + @@vit it says there is no such method for the nil class. I think this further confirms my suspicion that those variables are somehow nil. Thank you.

module Test
  RED = "rose"
  BLUE = "ivy"
  @myg = 9
  @@vit = 24.6
end
class Xy
  include Test;
  def initialize(n)
    @garb = n
  end
  attr_accessor :garb;
  def garbTest
    @garb = @myg;
  end
  def exo
    return 50;
  end
end

ryu = Xy.new(16);
ryu.garbTest;
puts "#{ryu.garb}";

Upvotes: 1

Views: 419

Answers (1)

Arup Rakshit
Arup Rakshit

Reputation: 118289

Because @myg is not shared variable. It is private property of module Test, thus while you included Test, @myg didn't come into Xy due to the mixin, it wouldn't come also by default. But, "Why nil?" - Because, instance variable, class variables are like that. Before initialising/defining them, if you attempt to use them, it will simply give you nil.

Small program to prove myself and Ruby :-

module Test
  @x = 10
  @@y = 11
end

class Foo
  include Test
end

Foo.instance_variable_defined?(:@x) # => false
Test.instance_variable_defined?(:@x) # => true
Foo.class_variable_defined?(:@@y) # => true
Test.class_variable_defined?(:@@y) # => true

You can define reader method inside Test singleton class, and then you can use it. Look below

module Test
  class << self
    attr_reader :myg
  end

  RED = "rose"
  BLUE = "ivy"
  @myg = 9
  @@vit = 24.6
end

class Xy
  include Test

  def initialize(n)
    @garb = n
  end

  attr_accessor :garb

  def garbTest
    @garb = Test.myg
  end

  def exo
    return 50
  end
end

ryu = Xy.new(16)
ryu.garbTest # => 9

Upvotes: 2

Related Questions