elz: (sisko)
elz ([personal profile] elz) wrote in [community profile] rubyonrails2009-04-16 08:39 pm

Instance variables in Ruby and Rails

I was trying to explain this to someone earlier while doing a couple other things and was making a muddle of it. So here's a somewhat-more-coherent explanation:



Ruby



If the terms 'class' and 'instance' are still unfamiliar to you, think of it this way:

class : instance
Superhero : batman
Vulcan : spock
Planet : earth
Website : dreamwidth

A class is a general type of thing, an instance is one of those things. So it follows pretty logically that a class variable stores information about the whole class and an instance variable stores information about an instance of that class. @@this is a class variable and @this is an instance variable.

Let's say my Superhero class looks like this:

class Superhero
  def secret_identity=(name)
    @secret_identity = name  
  end
	
  def secret_identity
    @secret_identity
  end
end


I can then create a new superhero like this:

batman = Superhero.new
batman.secret_identity = "Bruce Wayne"


And then when I type in batman.secret_identity again, it should say "Bruce Wayne". If I then do:

superman = Superhero.new
superman.secret_identity = "Clark Kent"


batman.secret_identity is still "Bruce Wayne", and superman.secret_identity is "Clark Kent".

So what you'll notice is:

  1. Each instance can have its own @secret_identity, and they don't conflict with one another.

  2. The value of @secret_identity sticks around and can be accessed and changed by any of the instance methods in the class. (You don't want to use instance variables in class methods, though. Badness will ensue.)

  3. I did have to create methods to let you access the instance variable from outside the class - you can't get to it directly.

  4. @secret_identity happens to be a string, but you could have an instance variable called @nemeses that stored an array of supervillains. Like all Ruby variables, instance variables can contain anything.


(NB: in practice, of course, always take steps to keep your secret identity from being read by the wrong people.)

Class variables are a bit less common, but you can imagine that the Vulcan class has something like this: @@shape_of_ears = "pointy". Doesn't really matter if you're talking about Spock or T'Pol: each Vulcan has pointy ears, and all Vulcans have pointy ears. The danger is that if you change @@shape_of_ears anywhere, it's changed everywhere. And you don't want to mess with Spock's ears.

Rails



So now we come to Rails, and if you've used Rails a bit already, you may be more rather than less confused, because instance variables are usually used in controllers and views, and they're specifically used to send information from the controller to the view. I put a bunch of people in @people in my controller action, and I can get those same people out of @people in my view file. What happened to not being able to access instance variables from outside the class they belong to?

This is actually Rails pulling a fast one on you. You're not accessing the controller's instance variables; what happens is that when a view is rendered, Rails takes all the instance variables in the controller action, clones them, and hands the clones off to the view. That's why you can get to the values of those variables when you render a view (either by default or by using 'render'), but not when you redirect - redirect_to sends you to a different controller action which renders its own view, giving you a whole different army of clones. So to speak.



Let me know if you have any questions, additions or corrections!

[personal profile] ex_rustler489 2009-04-18 05:58 pm (UTC)(link)
Oh, bless you. As someone coming in with zero programming experience, the terminology is one of the biggest stumbling blocks. This is marvelous. Thanks!

cxrAopYAhUGQC

(Anonymous) 2013-05-28 07:02 am (UTC)(link)
The core ethical value that shows most in the book Seedfolks is recsept because when they come together to grow the garden, they have to recsept everyones ideas, personalities, cultures, races, and abilities. Without recsept they wouldn't be able to work together growing the garden, and nobody would like each other.

ISvinBHuCWroLifD

(Anonymous) 2013-06-08 07:16 pm (UTC)(link)
I just created a brand new SC 6.2 site and added the CustomItemGenerator scuore to my solution as another project. I installed the package into my site, then built the scuore to overwrite the package's CustomItemGenerator.dll. I tried to generate custom item classes for a sample dummy template and the generate button doesn't seem to do anything still.I checked what the button does in the core and saw it calls devtools:generatecustomitem(id=$Target) so I'm thinking maybe something isn't hooking in. I looked in the CustomItemGeneratorCommand class and saw that if you try to generate custom items on any items other than a template or template folder, there should be a sheer alert in SC, which I don't get.

goHcjAveZuEfCa

(Anonymous) 2013-06-09 01:38 am (UTC)(link)
Thanks for keeping on top of this whole mess, and for surmamizing it in such a clear way. ("senior wtf correspondent" is such an appropriate tag for it) I guess I should start a Dreamwidth account as a back up or something, but most of my f-list and communities are staying, and I'm not active in any fandoms to expend the energy of finding and participating in new communities and all that. And maybe I'm just being too cynical here, but if Dreamwidth keeps getting more popular and expanding, then sooner or later the costs of operation will force them to choose whether or not to they view their userbase as a product to be sold. Same as LJ and all the other social networks.One thing is for sure: this whole debacle has made me so glad that I never signed up for Facebook. This certainly puts in me in the minority in my age group and has probably cost me, socially speaking, but man I sure as hell don't plan on signing up any time soon.