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 `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
···
On Thu, Apr 08, 2010 at 10:36:10PM +0900, Sask Khan wrote:
--
Daniel Bye
_
ASCII ribbon campaign ( )
- against HTML, vCards and X
- proprietary attachments in e-mail / \