Jeff Storey
Jeff Storey

Reputation: 57212

ruby Initializing instance variable outside method

As an experiment, I wrote some code that looks like

class MyClass

    @var = 100

    def hello
      p "hello"
    end

end

I know that if I do MyClass.new that @var is not defined on that object, rather I think this would define @var on the class MyClass.

Is there a practical usage to this?

Upvotes: 2

Views: 2840

Answers (2)

Linuxios
Linuxios

Reputation: 35788

It does have a use: Class variables. The normal Ruby class variable implementation, @@, shares the same variable between a superclass and its subclasses:

class A
  @@v = 0
  def self.v; @@v; end
  def self.v=(val); @@v=val; end
end
class B < A; end
A.v #-> 0
A.v= 3 #-> 3
B.v #->3
B.v= 42 #-> 42
A.v #-> 42

Obviously, this is pretty useless (except for the fact that, unlike class instance variables, class variables are also accessible directly in instance methods, as opposed to through self.class). But the same example with class instance variables:

class A
  @v = 0
  def self.v; @v; end
  def self.v=(val); @v=val; end
end
class B < A; end
A.v #-> 0
A.v= 3 #-> 3
B.v= 42 #-> 42
A.v #-> 3

Also, class instance variables can harness all of the metaprogramming already written for instance variables, like so:

class Foo
  class << self
    attr_accessor :v #Uses a class instance variable
  end
end

Upvotes: 7

Max
Max

Reputation: 22385

If you make accessor methods for @var

MyClass.singleton_class.class_eval { attr_accessor :var }

then you can treat @var like a class variable. The difference is that it won't be inherited by subclasses of MyClass.

_why takes advantage of this in Dwemthy's Array.

Upvotes: 1

Related Questions