--ZGiS0Q5IWpPtfppv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Thu, Apr 08, 2010 at 10:36:10PM +0900, Sask Khan wrote:
> 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

-- 
Daniel Bye
                                                                     _
                                              ASCII ribbon campaign ( )
                                         - against HTML, vCards and  X
                                - proprietary attachments in e-mail / \

--ZGiS0Q5IWpPtfppv
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.14 (FreeBSD)

iEYEARECAAYFAku98d8ACgkQixf5fBYiFmol7ACcCS4SZ0ujfedvyeUNOidv/BmN
v9gAn0YSEbjFVRNPk6SUxvgtyudPc6cr
Es
-----END PGP SIGNATURE-----

--ZGiS0Q5IWpPtfppv--