Trying to understand something about instance variables

My question is based on the following code from the agile book:

File: depot_f/app/controllers/store_controller.rb

private
def find_cart
session[:cart] ||= Cart.new

File: depot_f/app/models/cart.rb

class Cart

Ö’attr_reader :items
def initialize
@items = []
end

def add_product(product)
@items << product
end
end

File: depot_f/app/controllers/store_controller.rb

def add_to_cart
@cart = find_cart
product = Product.find(params[:id])
@cart.add_product(product)
end

Ok, so correct me if Im wrong, but dont instance variables only last
till the end of the method?

So how is it possible to keep appending items to the instance array
named @items?

Sorry for the newbie question, but I need to get this cleared up so I
can move on.

Thanks in advance

Kristen

class Cart

till the end of the method?

So how is it possible to keep appending items to the instance array
named @items?

Sorry for the newbie question, but I need to get this cleared up so I
can move on.

You’re right about instance variables… but way up at the top is the
line:

session[:cart] ||= Cart.new

This line checks to see if sesion[:cart] exists and if it doesn’t, it
sets
it to a new Cart. Then it returns that cart object (either a new one or
from the session). This happens a bit farthe down in the line:

@cart = find_cart

At which point you have a valid @cart which has as instance variables
@items as they were saved in the session from the last request.

-philip

  1. Next, a Product object is created as a result of a find from the
    database using an id parameter from the request. It’s only a local
    variable and it’s called product.
  2. The product is added to the @cart.

Hmm, Im kinda getting the idea now, but could you clarify the difference
between an instance variable and a local variable. How do I know when I
should use an instance or a local variable. Is there a rule of thumb?

Thanks you for your replies so far.

Kristen,

I think that the statement, “Instance variables only last till the
end of the method” is incorrect. Instance variables live as long as
their containing object lives. So, the Cart object has an instance
variable (an array) called @items. If your statement were true, there
would be no point in adding anything to it because @items would
disappear before anything useful can be done.

Here’s what’s going on starting with store_controller#add_to_cart:

  1. You’re creating a Cart object as a result of a find from the
    database and calling it @cart.
  2. Next, a Product object is created as a result of a find from the
    database using an id parameter from the request. It’s only a local
    variable and it’s called product.
  3. The product is added to the @cart.
  4. The controller method ends. By default, Rails looks for a .rhtml
    file called /app/views//. By convention, store is
    the controller name, and add_to_cart is the action name.
  5. Presumably, you want to show what’s in the cart in the view.
    That’s one reason why you’re using an instance variable-- to make it
    visible to the view. The local variable, product, is not available to
    the view.

Hope it helps,

-Anthony

An instance variable will be available to embedded ruby calls in your
rhtml templates; a local variable will only be available within the
method
it’s defined in.

In the example from AWDWR you quoted:

def add_to_cart
@cart = find_cart
product = Product.find(params[:id])
@cart.add_product(product)
end

@cart is an instance variable (denoted with an @ symbol), because it’s
an
instance of the Cart object. Product is a local variable, its scope is
local to the action (method) add_to_cart. @cart can be exposed in web
pages, but product cannot.

Further down AWDWR shows the instance variable @cart exposed in the
add_to_cart.rhtml template:

Your Pragmatic Cart

    <% for item in @cart.items %>
  • <%= item.title %>
  • <% end %>

The rule of thumb is: to make data visible to your user, use an instance
variable. The AWDWR book does a much better job of illustrating these
details.

Hope this helps!

Regards,
Dave


Information and Educational Technology
Kwantlen University College - 604-599-2120
“So powerful is the light of unity that it can illuminate the whole
earth.” --Bahá'u’lláh

Kristen [email protected]
Sent by: [email protected]
02/03/2007 06:14 PM
Please respond to
[email protected]

To
[email protected]
cc

Subject
[Rails] Re: Trying to understand something about instance variables.

  1. Next, a Product object is created as a result of a find from the
    database using an id parameter from the request. It’s only a local
    variable and it’s called product.
  2. The product is added to the @cart.

Hmm, Im kinda getting the idea now, but could you clarify the difference
between an instance variable and a local variable. How do I know when I
should use an instance or a local variable. Is there a rule of thumb?

Thanks you for your replies so far.


Posted via http://www.ruby-forum.com/.

@cart is an instance variable (denoted with an @ symbol), because it’s
an
instance of the Cart object. Product is a local variable, its scope is
local to the action (method) add_to_cart. @cart can be exposed in web
pages, but product cannot.

I realy appreciate the tips guys. There is one mroe thing that Im not
quite clear about.

The method

def add_to_cart
@cart = find_cart
product = Product.find(params[:id])
@cart.add_product(product)
end

Is the @cart in @cart = find_cart the same @cart on the line
@cart.add_product(product)?

I understand that the first line is either retrieving or creating a new
object in the session. So, is the third line just referencing that same
@cart object or is it going into the model cart and invoking the
add_product method?

Thank you!

The decision about the visibility depends on the encapsulation principle
in
object oriented programming. The variables that you declare must have as
minimal visibility as possible to get the job done. The reason is that
this
principle results in better quality software due to lower coupling.

You should read about basic OOP book if you are not familiar with basic
concepts. Here is a some good books: Object Oriented Software
Construction
by Bertrand Meyer, Object Oriented Design Heuristics by Arthur J. Riel
and
if you want a freebie, my book available for free at
http://guide.zepho.com/version1/http://www.amazon.com/Object-Oriented-Software-Construction-Prentice-Hall-International/dp/0136291554/ref=pd_bbs_sr_1/104-8023659-2852731?ie=UTF8&s=books&qid=1172905283&sr=1-1