Instance variables in Ruby and Rails
Apr. 16th, 2009 08:39 pm![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
![[community profile]](https://www.dreamwidth.org/img/silk/identity/community.png)
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:
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:
I can then create a new superhero like this:
And then when I type in batman.secret_identity again, it should say "Bruce Wayne". If I then do:
batman.secret_identity is still "Bruce Wayne", and superman.secret_identity is "Clark Kent".
So what you'll notice is:
(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.
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!
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:
- Each instance can have its own @secret_identity, and they don't conflict with one another.
- 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.)
- I did have to create methods to let you access the instance variable from outside the class - you can't get to it directly.
- @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!
(no subject)
Date: 2009-04-17 08:49 am (UTC)(no subject)
Date: 2009-04-17 11:25 am (UTC)bGwEQvVLTfo
Date: 2013-05-28 05:31 am (UTC)upBVyYzdFSfkcZoGG
Date: 2013-05-26 08:24 am (UTC)(no subject)
Date: 2009-04-18 01:33 am (UTC)(no subject)
Date: 2009-04-18 01:41 pm (UTC)afRdpumSfSACKyu
Date: 2013-05-28 05:34 am (UTC)btGSkZlXgO
Date: 2013-06-11 12:01 pm (UTC)GpDqDdNXpToy
Date: 2013-05-26 06:22 am (UTC)(no subject)
Date: 2009-04-18 05:58 pm (UTC)cxrAopYAhUGQC
Date: 2013-05-28 07:02 am (UTC)ISvinBHuCWroLifD
Date: 2013-06-08 07:16 pm (UTC)goHcjAveZuEfCa
Date: 2013-06-09 01:38 am (UTC)(no subject)
Date: 2009-05-25 10:12 pm (UTC)(no subject)
Date: 2009-05-25 10:29 pm (UTC)hkRHlRPjfxcvLVkR
Date: 2013-05-26 07:14 pm (UTC)JkffYZKlPicdpps
Date: 2013-05-28 06:07 am (UTC)MgfQHCSDMYSFwfeDjKm
Date: 2013-05-28 04:56 am (UTC)KVwdsCZyDPJUebpH
Date: 2013-05-28 06:56 am (UTC)mXMqEcNzKtdRSFRqH
Date: 2013-06-09 12:16 am (UTC)QOwpSgNFzHORGZcuq
Date: 2013-06-09 09:08 am (UTC)Hello my friends!
Date: 2009-09-17 07:32 pm (UTC)dveeQvPsQxKZyVWiHbu
Date: 2013-05-28 05:20 am (UTC)