# Ruby newbie - Trying to understand variables

**URL:** <https://www.ruby-forum.com/t/ruby-newbie-trying-to-understand-variables/186537>\
**Category:** Ruby\
**Created:** [April 8, 2010, 3:36pm UTC](https://www.ruby-forum.com/t/ruby-newbie-trying-to-understand-variables/186537 "2010-04-08T15:36:07Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![kayote](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/cdc98d/32.png) [@kayote](https://www.ruby-forum.com/u/kayote)\
**Post date:** [April 8, 2010, 3:36pm UTC](https://www.ruby-forum.com/t/ruby-newbie-trying-to-understand-variables/186537/1 "2010-04-08T15:36:07Z")

</div>

Hey guys,

Im new to Ruby and totally new to the concept of Object Oriented  
Programming.

At the moment, am going through Pragmatic Programmerâ€™s Ruby and even  
though am finding it to awesome, I have a few questions

Below is the exercise we are going through in the chapter â€˜Classes,  
Object & Variablesâ€™:

classBookInStock  
attr\_reader :isbn, :price  
Def initialize(isbn,price)  
@isbn = isbn  
@price = Float(price)  
end  
Def price=(new\_price)  
@price = new\_price  
end  
#…  
End  
book=BookInStock.new(“isbn1”,33.80)  
Puts “ISBN = #{book.isbn}”  
puts"Price = #{book.price}"  
book.price = book.price\*0.75 #discount price  
puts"Newprice= #{book.price}"

Im a bit confused about the output syntax using â€˜Putsâ€™. Now, I read and  
understand that the variable â€˜@isbnâ€™ is not the same as â€˜isbnâ€™ variable,  
same for the â€˜:isbnâ€˜ constant, all three being different to eachother.  
The variable with â€˜@â€™ is available outside the place where it is defined  
so why are we not using the following code:

Puts â€œISNB = #{book.@isbn}â€

Instead of (as per the code in the exercise above)

puts â€œisbn= #{book.isbn}â€

The reason I think we should be using the variable with @ is because the  
one without @ is not accessible outside where it is defined, right? And  
as the two variables (@isbn, isbn) are different to each other. Also,  
how is the constant â€˜:isbnâ€™ in â€˜attr\_readerâ€™ connected to the â€˜isbnâ€™  
variable when we didnâ€™t connect them?

Any help would be most appreciated.

---

<div class="post-metadata">

**Author:** ![kayote](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/cdc98d/32.png) [@kayote](https://www.ruby-forum.com/u/kayote)\
**Post date:** [April 8, 2010, 4:03pm UTC](https://www.ruby-forum.com/t/ruby-newbie-trying-to-understand-variables/186537/2 "2010-04-08T16:03:33Z")

</div>

Isbn is property of object book. The properties are accessible via dot  
operator on object instance. However within the object itself it is same  
property is available as instance variable and hence the @ sign before  
it.

---

<div class="post-metadata">

**Author:** ![kayote](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/cdc98d/32.png) [@kayote](https://www.ruby-forum.com/u/kayote)\
**Post date:** [April 8, 2010, 4:15pm UTC](https://www.ruby-forum.com/t/ruby-newbie-trying-to-understand-variables/186537/3 "2010-04-08T16:15:32Z")

</div>

With the class BookInStock you must refer to the instance variable  
isbn with the @ in front to show that it is an instance variable.  
Within a BookInStock method for example, @isbn refers to the isbn  
instance variable owned by the instance that method was called on.

Outside of the class definition, you have created an instance of  
BookInStock and called that instance book. There, book.isbn refers to  
the method called isbn that’s defined on BookInStock.

Finally, attr\_reader is a method which takes :isbn (the symbol) as a  
parameter, and generates the necessary ‘getter’ method to access the  
@isbn instance variable from outside the class definition. This is  
what wires up book.isbn to @isbn in the class definition.

attr\_reader :isbn

is the same as

def isbn  
@isbn  
end

Hope that helps!

Paul S.

removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![kayote](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/cdc98d/32.png) [@kayote](https://www.ruby-forum.com/u/kayote)\
**Post date:** [April 8, 2010, 4:20pm UTC](https://www.ruby-forum.com/t/ruby-newbie-trying-to-understand-variables/186537/4 "2010-04-08T16:20:48Z")

</div>

When you use attr\_reader it declares a method on your class for you like  
this:

def isbn  
return @isbn  
end

You’re correct that the variable in your constructor is local to that  
scope. When you call book.isbn you are actually calling the method above  
which correctly returns the instance variable.

Similarly if you used attr\_accessor or attr\_writer you would get a  
setter method:

def isbn=(val)  
@isbn = val  
end  
dan drew \> brilliantsoftware.ca \> shouldn’t your software be brilliant?

From: Sask Khan  
Sent: Thursday, April 08, 2010 9:36 AM  
Newsgroups: comp.lang.ruby  
To: ruby-talk ML  
Subject: Ruby newbie - Trying to understand variables

Hey guys,

Im new to Ruby and totally new to the concept of Object Oriented  
Programming.

At the moment, am going through Pragmatic Programmerâ€™s Ruby and even  
though am finding it to awesome, I have a few questions

Below is the exercise we are going through in the chapter â€˜Classes,  
Object & Variablesâ€™:

classBookInStock  
attr\_reader :isbn, :price  
Def initialize(isbn,price)  
@isbn = isbn  
@price = Float(price)  
end  
Def price=(new\_price)  
@price = new\_price  
end  
#…  
End  
book=BookInStock.new(“isbn1”,33.80)  
Puts “ISBN = #{book.isbn}”  
puts"Price = #{book.price}"  
book.price = book.price\*0.75 #discount price  
puts"Newprice= #{book.price}"

Im a bit confused about the output syntax using â€˜Putsâ€™. Now, I read and  
understand that the variable â€˜@isbnâ€™ is not the same as â€˜isbnâ€™ variable,  
same for the â€˜:isbnâ€˜ constant, all three being different to eachother.  
The variable with â€˜@â€™ is available outside the place where it is defined  
so why are we not using the following code:

Puts â€œISNB = #{book.@isbn}â€

Instead of (as per the code in the exercise above)

puts â€œisbn= #{book.isbn}â€

The reason I think we should be using the variable with @ is because the  
one without @ is not accessible outside where it is defined, right? And  
as the two variables (@isbn, isbn) are different to each other. Also,  
how is the constant â€˜:isbnâ€™ in â€˜attr\_readerâ€™ connected to the â€˜isbnâ€™  
variable when we didnâ€™t connect them?

Any help would be most appreciated.

---

<div class="post-metadata">

**Author:** ![kayote](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/cdc98d/32.png) [@kayote](https://www.ruby-forum.com/u/kayote)\
**Post date:** [April 9, 2010, 9:53am UTC](https://www.ruby-forum.com/t/ruby-newbie-trying-to-understand-variables/186537/5 "2010-04-09T09:53:03Z")

</div>

Hasham Malik wrote:

> …

Dan D. wrote:

> …

Daniel B. wrote:

> …

Hasham, Dan & Daniel, thanks for the clarification.

Best,

---

<div class="post-metadata">

**Author:** ![kayote](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/cdc98d/32.png) [@kayote](https://www.ruby-forum.com/u/kayote)\
**Post date:** [April 8, 2010, 5:11pm UTC](https://www.ruby-forum.com/t/ruby-newbie-trying-to-understand-variables/186537/6 "2010-04-08T17:11:09Z")

</div>

On Thu, Apr 08, 2010 at 10:36:10PM +0900, Sask Khan wrote:

> End  
> so why are we not using the following code:
> 
> Puts ???ISNB = #{book.@isbn}???
> 
> Instead of (as per the code in the exercise above)
> 
> puts ???isbn= #{book.isbn}???

The `isbn' in`book.isbn’ isn’t actually a variable - it is an accessor  
method call, which retrieves the value held in the variable `@isbn' that you defined and assigned a value to in the class definition. The accessor was defined for you when you said`attr\_reader :isbn, :price’, which is  
Ruby  
shorthand for saying this:

def isbn  
@isbn  
end  
def price  
@price  
end

Within the class definition, variables whose names begin with `@' are instance variables - each instance of the class will have its own variable @isbn, which is unique to that instance. In the class definition, you can use the`@isbn’ notation to refer to the value held in the variable,  
but outside the class, you need to use accessor methods instead. Google  
for “OOP encapsulation” for more details.

`:isbn' is a Ruby Symbol, not a constant (a Ruby constant's name begins with an uppercase letter, so in fact BookInStock, your class name, is a constant). A Ruby symbol is used, in this context, to refer to the variable by name, rather than to dereference the value that it holds. So the call to attr_reader essentially says "define attribute reader methods for the variables called`isbn’ and `price'". It is as if you had manually defined a method for each of`isbn’ and `price’, as I did above.

While isbn, @isbn and :isbn are conceptually related in this context,  
they  
are three different things. To add to the confusion, note that `isbn’ in  
the method signature for the initialize method in your class is a fourth  
thing! It is a local variable that goes out of scope as soon as its  
outer-  
most enclosing block ends. In this case, it ceases to exist once Ruby  
hits  
the end of the method definition. Therefore, in order to keep the value  
around, you assign it to the instance variable @isbn, which only  
disappears  
once the instance itself goes away.

> The reason I think we should be using the variable with @ is because the  
> one without @ is not accessible outside where it is defined, right? And  
> as the two variables (@isbn, isbn) are different to each other.

As already stated, book.isbn is a call to the accessor method `isbn' on the instance`book’ of class BookInStock. It just happens to return the  
value  
held within the instance variable @isbn on the instance, a connection  
made  
by the call to `attr\_reader’.

I hope this helps!

Dan
