# Trying to understand something about instance variables

**URL:** <https://www.ruby-forum.com/t/trying-to-understand-something-about-instance-variables/87483>\
**Category:** Rails\
**Created:** [March 2, 2007, 10:29pm UTC](https://www.ruby-forum.com/t/trying-to-understand-something-about-instance-variables/87483 "2007-03-02T22:29:35Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Kristen](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/c4cdca/32.png) [@Kristen](https://www.ruby-forum.com/u/Kristen)\
**Post date:** [March 2, 2007, 10:29pm UTC](https://www.ruby-forum.com/t/trying-to-understand-something-about-instance-variables/87483/1 "2007-03-02T22:29:35Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Kristen](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/c4cdca/32.png) [@Kristen](https://www.ruby-forum.com/u/Kristen)\
**Post date:** [March 2, 2007, 10:56pm UTC](https://www.ruby-forum.com/t/trying-to-understand-something-about-instance-variables/87483/2 "2007-03-02T22:56:40Z")

</div>

> 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

---

<div class="post-metadata">

**Author:** ![Kristen](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/c4cdca/32.png) [@Kristen](https://www.ruby-forum.com/u/Kristen)\
**Post date:** [March 3, 2007, 3:14am UTC](https://www.ruby-forum.com/t/trying-to-understand-something-about-instance-variables/87483/3 "2007-03-03T03:14:08Z")

</div>

> 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.

---

<div class="post-metadata">

**Author:** ![Kristen](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/c4cdca/32.png) [@Kristen](https://www.ruby-forum.com/u/Kristen)\
**Post date:** [March 2, 2007, 11:16pm UTC](https://www.ruby-forum.com/t/trying-to-understand-something-about-instance-variables/87483/4 "2007-03-02T23:16:42Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Kristen](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/c4cdca/32.png) [@Kristen](https://www.ruby-forum.com/u/Kristen)\
**Post date:** [March 3, 2007, 3:59am UTC](https://www.ruby-forum.com/t/trying-to-understand-something-about-instance-variables/87483/5 "2007-03-03T03:59:06Z")

</div>

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 [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
Sent by: removed\_email\_address@domain.invalid  
02/03/2007 06:14 PM  
Please respond to  
removed\_email\_address@domain.invalid

To  
removed\_email\_address@domain.invalid  
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/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![Kristen](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/c4cdca/32.png) [@Kristen](https://www.ruby-forum.com/u/Kristen)\
**Post date:** [March 4, 2007, 12:43am UTC](https://www.ruby-forum.com/t/trying-to-understand-something-about-instance-variables/87483/6 "2007-03-04T00:43:21Z")

</div>

> @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!

---

<div class="post-metadata">

**Author:** ![Kristen](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/c4cdca/32.png) [@Kristen](https://www.ruby-forum.com/u/Kristen)\
**Post date:** [March 3, 2007, 8:07am UTC](https://www.ruby-forum.com/t/trying-to-understand-something-about-instance-variables/87483/7 "2007-03-03T08:07:19Z")

</div>

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://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](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)
