class Body
@feet = 2
puts "We have #{@feet} feet"
def initialize
end
def report
puts "We have #{@feet} feet"
end
end
b=Body.new
b.report
Why is it in the above class the first puts prints correctly but the second
puts doesn't have a value for the instance variable?
When you have a variable with @ in front, it's an instance variable of
the object which
is self when the variable is created. In your case, @feet is created
when self is the class
object Body. It is not an instance variable of an object of class
Body, as it would if you
did this:
irb(main):001:0> class Body
irb(main):002:1> def initialize
irb(main):003:2> @feet = 3
irb(main):004:2> end
irb(main):005:1> def report
irb(main):006:2> puts "We have #{@feet} feet"
irb(main):007:2> end
irb(main):008:1> end
=> nil
irb(main):009:0> Body.new.report
We have 3 feet
Classes are also objects themselves and can have instance variables
just as any other object:
irb(main):010:0> class Body
irb(main):011:1> @feet = 2
irb(main):012:1> class << self
irb(main):013:2> attr_accessor :feet
irb(main):014:2> end
irb(main):015:1> end
=> nil
irb(main):016:0> Body.feet
=> 2
irb(main):017:0> class Body
irb(main):018:1> def self.report
irb(main):019:2> puts "We have #{@feet} in the class Body"
irb(main):020:2> end
irb(main):021:1> end
=> nil
irb(main):022:0> Body.report
We have 2 in the class Body
Now, the variable @feet above is a different object from the @feet in
my first example. In fact you can have both and they won't interfere.
You just have to understand who is "self" in each context:
irb(main):023:0> class Body
irb(main):024:1> @feet = 2
irb(main):025:1> class << self
irb(main):026:2> attr_accessor :feet
irb(main):027:2> def class_report
irb(main):028:3> "We have #{@feet} in class Body"
irb(main):029:3> end
irb(main):030:2> end
irb(main):031:1> def initialize
irb(main):032:2> @feet = 3
irb(main):033:2> end
irb(main):034:1> def report
irb(main):035:2> "We have #{@feet} in the instances of class Body"
irb(main):036:2> end
irb(main):037:1> end
=> nil
irb(main):038:0> Body.feet
=> 2
irb(main):039:0> Body.report
We have 2 in the class Body
=> nil
irb(main):040:0> b = Body.new
=> #<Body:0xb7c2c4fc @feet=3>
irb(main):041:0> b.report
=> "We have 3 in the instances of class Body"
Hope this helps,
Jesus.