27
votes

Ruby has 5 variable scopes:

  1. Local Variables: these are the normal variables, example x = 25, y = gaurish where x and y are local variables.
  2. Instance Variables: these are denoted with @ symbol infront of the actual variable name. mainly used with classes, so that each instance/object of the class has a different/separate value. example. @employee.name = 'Alex'
  3. Class Variables: denoted with @@ symbols in front of variable name. class variable, I think have same value accos all instances/object.
  4. Global variables: they start with $ symbol and are accessible everywhere. example $LOAD_PATH
  5. Constants: Must start with Capital letter but by convention written in ALL_CAPS. although, it is a constant but its value its not constant and can be changed(ruby will throw a warning, though). so in the sense, this also acts like a variable.

As you may notice,all of the above are variables which store some value of some type and their value can be changed. But, each scope does something little bit different. Having 5 different types of variable scopes is confuses hell out of me. Mainly, I have difficulty deciding under what case, I should be using a particular scope in my code. so I have some questions in my mind. please answer:

  1. I notice that local variables and class variables stay same for all objects/instances, unlike instance variables. so what difference between Local variables and Class variables?
  2. Can local variables be used in place of class variables? or vice-versa. And if yes, then why, and if no, then why not?
  3. Global variables in ruby remind me of the evil global $x variables in PHP. Are global variables in ruby also considered evil and therefore should not be used. OR, there are specific cases where it makes sense to use global variables in ruby?
  4. Why constants are not constants and allow their value to be changed? A constant's value by definition should be constant right? else, we can just use another variable and don't change its value. would that be equivalent to a CONSTANT in ruby?
  5. Any page/resource/link which explains the difference between 5 different variable scopes in ruby? I like to keep one handy for reference.
  6. Under what use-case, I should be using a particular variable scope in my code. so one would explain all 5 cases with can example that would be cool, this is my main reason for confusion.
  7. is there a de facto choice like public in java? Which would be the safe bet in most use-cases?

Thanks for taking time to read and answer question

4
For point one, all objects share class level variables, each individual object will have its own copy of the local variableHunter McMillen
If each individual object will have its own copy of the local variable, isn't local variables more like instance variables then?CuriousMind
Sort of, I suppose you could see them that way. Instance variables belong to an instance of an object and usually make up properties of that object. For example a Person object might have two instance variables @first_name and @last_name, it might also have a local variable x but x is unrelated to the state of the Person objectHunter McMillen

4 Answers

14
votes
  1. Class variables are the same for all instances, because they're class variables–associated with the class. Everything access the same variable, including each instance.

  2. No. Local variables are just that–local. They may be local to a function, or local to the class declaration, which is different than being a class variable. Locals in a class declaration go out of scope when the class declaration ends.

  3. That's because they're exactly the same–they're global. Global state is always evil; this is not a property of the language or environment. That said, some global state may be required–that's just the way it is. It makes sense to use global state when there's global state. The trick is to use global state properly, which is sometimes a non-trivial endeavor.

  4. That's just how Ruby is.

  5. One has already been given by Chris.

  6. I would think this question would be largely self-answering. Global when the entire world needs access. Instance when it's specific to a class instance. Local when it's only required in a local scope (e.g., a method, a block (note differences between 1.8 and 1.9 with regard to block scope), etc.) Constant when the variable isn't supposed to change. A class variable when it's something that either every instance needs, or if exposed via a class method, something tightly associated with a class.

  7. There is no "most use-cases", it totally depends on what you're doing with the variable. And public isn't the de facto choice in Java–it depends on the entity in question. Default Java scope is package-private (methods, properties). Which to use in Ruby depends entirely upon the use-case, noting that as with Java, and even more easily in Ruby, things can be circumvented.

7
votes

Local variables are not equivalent to class ones, they are tied to the block you are in. Any local declared in a block can be used there. Class variables are tied to the class structure you are in. Defining a class is itself a block, so you might be able to access local variables similarly, but you'll find if you refer to your class in a different context you cannot refer to the local variable in the same fashion.

Global variables are considered bad form, if abused. OOP should help you structure your programs such that constants on the entire program aren't needed. Think of them as actually being global: if you can't vouch for its consistency to the entire world, like the value of PI or whether or not you love your wife, you probably shouldn't be making promises.

Once you get the hang of them, I find "Ruby Variable Scope" to be a good reference.

2
votes

I found a good and in-depth explanation regarding different scopes and their visibilities in Ruby in the following link .Scopes and Visibilities with Examples in detail.

According to it ,

Class variable (@@a_variable): Available from the class definition and any sub-classes. Not available from anywhere outside.

Instance variable (@a_variable): Available only within a specific object, across all methods in a class instance. Not available directly from class definitions.

Global variable ($a_variable): Available everywhere within your Ruby script.

Local variable (a_variable): It is available only in the particular method or block in ruby script. 

Some more explanation regarding Instance variables is : You can access instance variables in any method of that particular class. While local variables can't be accessed outside of the method. Below is an example from ruby monk which explains this concept thoroughly.

class Item

   def initialize(item_name, quantity)

       @item_name = item_name   
       @quantity = quantity

   end

  def show

   puts @item_name
   puts @quantity
   supplier = "Acme corp"
   puts supplier

  end
end

 Item.new("tv",1).show

Here supplier is a local variable which can be accessed from show method only in our example.Just try to declare the supplier variable in the initialize method and printing it out in show method. It will give an error as undefined variable supplier.

i hope it helps. :)

1
votes

Here is my two cents for this and is writing for c++/java/c# programmers:

A Ruby local/$Global variable is a bit like c++/java/c#'s local/Global variable.

A Ruby @instance variable it's like c++/java/c#'s member variable /class property which can be accessible in any member function/class method.Though Ruby instance can be applied not only to class but also to Ruby Module.

A Ruby @@class variable is like as c++/java's static member variable which is share between all instances of the same class.