# Can Someone Explain This to Me?

**URL:** <https://www.ruby-forum.com/t/can-someone-explain-this-to-me/146348>\
**Category:** Ruby\
**Created:** [August 20, 2008, 7:42am UTC](https://www.ruby-forum.com/t/can-someone-explain-this-to-me/146348 "2008-08-20T07:42:47Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![rgreen](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/f04885/32.png) [@rgreen](https://www.ruby-forum.com/u/rgreen)\
**Post date:** [August 20, 2008, 7:42am UTC](https://www.ruby-forum.com/t/can-someone-explain-this-to-me/146348/1 "2008-08-20T07:42:47Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![rgreen](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/f04885/32.png) [@rgreen](https://www.ruby-forum.com/u/rgreen)\
**Post date:** [August 20, 2008, 7:55am UTC](https://www.ruby-forum.com/t/can-someone-explain-this-to-me/146348/2 "2008-08-20T07:55:04Z")

</div>

On Wed, Aug 20, 2008 at 7:38 AM, Ron G. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> 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.

---

<div class="post-metadata">

**Author:** ![rgreen](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/f04885/32.png) [@rgreen](https://www.ruby-forum.com/u/rgreen)\
**Post date:** [August 21, 2008, 4:15am UTC](https://www.ruby-forum.com/t/can-someone-explain-this-to-me/146348/3 "2008-08-21T04:15:12Z")

</div>

On Wednesday 20 August 2008 00:38:43 Ron G. wrote:

> 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?

Well, in this case, you’re defining an instance variable… on Body, the  
class:

> class Body  
> @feet = 2

You see, classes are objects, too. You can treat them like normal  
objects:

b = Body  
c = b.new

The normal way to do what I think you’re wanting to do here is:

class Body  
def initialize  
@feet = 2  
end  
end

By the way, you can leave out initialize if you have nothing to  
initialize.

Of course, if you’re only supporting humans, you could do this:

class Body  
FEET = 2  
def report  
puts “We have #{FEET} feet”  
end  
end

One more thing: I don’t often use instance variables directly. That  
gives me  
more flexibility – I can do something like this:

class Body  
attr\_reader :feet  
def initialize  
@feet = 2  
end  
def report  
puts “We have #{feet} feet”  
end  
end

That way, I could change to using a constant without touching the  
“report”  
method. The next version would look like this:

class Body  
FEET = 2  
def feet  
FEET  
end  
…  
end

But it’s getting a bit silly talking about feet, so I’ll stop.
