Question

If I have the following piece of Ruby code:

class Blah
  def self.bleh
    @blih = "Hello"
    @@bloh = "World"
  end
end

What exactly are @blih and @@bloh? @blih is an instance variable in the class Blah, and @@bloh is a class variable in the class Blah, correct? Does it mean that @@bloh is a variable in Blah's class, Class?

Was it helpful?

Solution

People seem to be ignoring that the method is a class method.

@blih will be instance variable of the instance of class Class for the constant Bleh. Hence:

irb(main):001:0> class Bleh
irb(main):002:1>   def self.bleh
irb(main):003:2>     @blih = "Hello"
irb(main):004:2>     @@blah = "World"
irb(main):005:2>   end
irb(main):006:1> end
=> nil
irb(main):007:0> Bleh.instance_variables
=> []
irb(main):008:0> Bleh.bleh
=> "World"
irb(main):009:0> Bleh.instance_variables
=> ["@blih"]
irb(main):010:0> Bleh.instance_variable_get :@blih
=> "Hello"

@@blah will be available as a class variable of Bleh:

irb(main):017:0> Bleh.class_variables
=> ["@@blah"]
irb(main):018:0> Bleh.send :class_variable_get, :@@blah
=> "World"

OTHER TIPS

There is a method to this madness...

class Example
  @foo # class instance variable
  @@bar # class variable

  def fun1
    @baz # instance variable
  end
end

Instance variables

Instance variables (@foo and @baz in the example) always begin with @, and they always belong to whatever object self refers to: either an object of the class, or the Class object representing a class. An instance variable reference in a class definition or class method is completely different from an instance variable reference in an instance method.

Inheritance
Because instance variables are not defined by a class, they are unrelated to the inheritance mechanism —they are simply created when a value is assigned to them. Class instance variables, being simply instance variables of the Class object that represents a class, are thus not inherited.

Class variables

Class variables are visible to, and shared by, the class methods and the instance methods of a class, and also by the class definition itself. Class variables can be used in instance methods, class methods, and in the class definition itself, outside of any method. Class variables are always evaluated in reference to the class object created by the enclosing class definition statement.

Class instance variable vs instance variable

A disadvantage of class instance variables is that they cannot be used within instance methods as class variables can. Another disadvantage is the potential for confusing them with ordinary instance variables. An advantage of class instance variables over class variables has to do with the confusing behavior of class variables when subclassing an existing class: if a class uses class variables, then any subclass can alter the behavior of the class and all its descendants by changing the value of the shared class variable. This is a strong argument for the use of class instance variables instead of class variables.

Much of this is from the excellent "The Ruby Programming Language"
alt text

A variable prefixed with two at signs is a class variable, accessible within both instance and class methods of the class.

Example:

class CountEm
  @@children = 0

  def initialize
    @@children += 1
    @myNumber = @@children
  end

  def whoAmI
    "I'm child number #@myNumber (out of #@@children)"
  end

  def CountEm.totalChildren
    @@children
  end
end

c1 = CountEm.new
c2 = CountEm.new
c3 = CountEm.new
c1.whoAmI              # -> "I'm child number 1 (out of 3)"
c3.whoAmI              # -> "I'm child number 3 (out of 3)"
CountEm.totalChildren  # -> 3

Example taken from link text

[edited for clarity]

In your example setting @blih will not be visible outside the scope of your class method, because inside a class method there's no instance to bind an instance variable to it.

Speaking of terminology, I'd say "@@bloh is a class variable in class Blah" but not "variable in Blah's class Class". Class "Class" remains untouched.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top