elz: (sisko)
[personal profile] elz posting in [community profile] rubyonrails
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!

JkffYZKlPicdpps

Date: 2013-05-28 06:07 am (UTC)
From: (Anonymous)
Hi Joel. I've noticed you guys rencltey through Google alerts Yeah, there's much to do here. I've set the project aside for now. Might get back to it later.

July 2010

S M T W T F S
    123
4567 8910
11121314151617
18192021222324
25262728293031

Page Summary

Style Credit

Expand Cut Tags

No cut tags