4
class Counter
   def self.counted_new
      @count = 0 if @count.nil?
      @count += 1
      new
   end

   def self.count
      @count
   end
end

In format, @count looks like a instance variable, but when I load this in "irb"(interface ruby) and type four command code

Counter.counted_new
Counter.count
Counter.counted_new
Counter.count

@count finally became 2! Acting like a class variable

2 Answers 2

9

@count is always an instance variable, but it can be an instance variable on a class if it is declared in that context.

In this case, @count is a class instance variable. In other words, by writing @count inside of a class level method you are assigning a variable to that class.

By writing @count inside of a instance method, you are assigning an instance variable that is available in that particular instance only.

If you declare a variable with @@count you get a class variable.

THe main difference between class variables and class instance variables is that class variables are retained in inheritance.

class Foo
  @@klass = "class level variable"
  @klass_instance = "class instance level variable"
end

class Bar < Foo
end


puts Foo.instance_variables.inspect # => [:@klass_instance]
puts Foo.class_variables.inspect  # => [:@@klass]

puts Foo.instance_variable_get(:@klass_instance)
# => "klass instance level variable"
puts Foo.class_variable_get(:@@klass)
# => "class level variable"

# The class variable is inherited, but the class instance variable is not

puts Bar.instance_variables.inspect # => []
puts Bar.class_variables.inspect  # => [:@@klass]

# The @@klass variable is shared between all classes in the downward inheritance chain
# So for example:
Foo.class_variable_set(:@@klass, "foo")
puts Bar.class_variable_get(:@@klass) # => "foo"
Sign up to request clarification or add additional context in comments.

6 Comments

Can you explain more specific? and can you teach me how to recognize these cases quickly? because it is well know that @blah is a instance variable
instance variables are for instances. since you did Counter.count_new you made it on the class not on the instance. So @count is an instance, but in the class. If you would have instantiated an instace like Counter.new.count_new it would be on the instance and not on the class
nice explanation by Jesper on explaining the difference between class variables and class instance variables
The one other difference between class instance variables and class variables is that class variables are also accessible in instance methods, not just class methods.
@NickGinanto I find that if I declear a new instance of Counter called Foo, then the @count instance in Foo doesn't share the same data field with the @count instance in class. Is it right?
|
4

The reason why this works, is because Classes themselves are instances. So the reason your variable behaves like a class variable, is because it's an instance variable of your class.

This is rather confusing for people new to Ruby, and it's also a question whether this is the right behaviour you're programming there. Normally class instances should be declared with double @.

The person here gives a good detailed explanation: Using Instance Variables in Class Methods - Ruby

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.