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.

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.

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.

[email protected]

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.

Hasham Malik wrote:

Dan D. wrote:

Daniel B. wrote:

Hasham, Dan & Daniel, thanks for the clarification.

Best,

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' inbook.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 saidattr_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 calledisbn’ and price'". It is as if you had manually defined a method for each ofisbn’ 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 instancebook’ 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