5

I am having some trouble understanding the syntax of variables and symbols in Ruby. I am reading a book called Agile Web Development with Rails 4. I am trying to learn both Ruby and Rails so that I can build websites.

The books and tutorials I have been reading sometimes have variables with the "@" symbol in front of them, and then some variables do not have the @ symbol in front of them. What is the difference between them?

Also, I am getting confused with the colon. Sometimes I see variables where the colon is in the front, such as :order, and then I see variables where the colon is at the end, such as colon:. I do not understand what the colon is doing.

Please help me understand the Ruby syntax.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Sameer Anand
  • 311
  • 1
  • 4
  • 11
  • 1
    Recommended reading: http://www.ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/index.html – Michael Berkowski Nov 04 '13 at 15:23
  • And [wade through several of these questions](http://stackoverflow.com/search?q=%5Bruby%5D+variable+%22%40%22) – Michael Berkowski Nov 04 '13 at 15:26
  • 2
    Since Rails is a framework built on Ruby, start with a Ruby tutorial to get a handle on the actual language, then move to Rails. – Reinstate Monica -- notmaynard Nov 04 '13 at 15:27
  • Sameer, diving into Ruby _and_ Rails at the same time is not easy but it's doable. I consider it a valid way of learning them - the "dive" method. You'll swallow a lot of water but don't be discouraged when people tell you "you have to learn Ruby first" because eventually you'll find your way around. – mjnissim Nov 04 '13 at 15:39
  • 1
    agreed with @iamnotmaynard. Without basic ruby knowledge, you will suffer hard with rails, especially when you will encounter metaprogramming and other clever ruby tricks that the rails contributors use... I'd recommmend those books : [the well grounded rubyist](http://www.manning.com/black2/), [eloquent ruby](http://eloquentruby.com/), [the ruby way](http://therubyway.org/) and of course [the universal reference : the pickaxe](http://pragprog.com/book/ruby/programming-ruby) – m_x Nov 04 '13 at 15:47
  • See "[Ruby — understanding symbols](http://stackoverflow.com/questions/2341837/understanding-symbols-in-ruby)", and follow the related links. – the Tin Man Nov 04 '13 at 15:50
  • @mjnissim It's possible, but masochistic - I know it for sure... that's what I've done ;). Rails is almost a DSL in itself, heavily uses advanced features of ruby (metaprog...) and boasts a LOT of magic that make it hard to understand what is going on if you don't have a solid ruby knowledge. Moreover, knowing the difference between the different kinds of vars is just the matter of following a basic tutorial, so I think it's a bare, reasonable minimum – m_x Nov 04 '13 at 15:51
  • @m_x I agree with you! It makes sense, and like you, I've also dived straight into Rails myself. As hard as it was, I don't regret it ha ha! – mjnissim Nov 04 '13 at 17:04

4 Answers4

11

Variables starting with @ are instance variables, "properties" in other languages. Whereas 'classic' variables are local to the scope of their method/block, instance variables are local to a specific instance of an object, for example:

class Foo

  def initialize(bar)
    @bar = bar
  end

  def bar
    @bar # the variable is specific to this instance
  end

  def buzz
    buzz = 'buzz' # this variable is not accessible outside of this method
  end

end

You may also see variables starting with @@, which are class variables, and are accessible by every instance of the class and shared with every instance of the subclass. Usage of those variables is usually discouraged, primarily because subclasses share the variable, which can cause a lot of mess.

In Ruby everything is an object, classes are objects (instances of class Class), so you can also have class instance variables:

class Foo

  def self.bar
    @bar #we are in class Foo's scope, which is an instance of class Class
  end

  def self.bar=(bar)
    @bar = bar
  end

  def bar
    @bar # Foo.new.bar != Foo.bar 
  end

end

What you call "variables with a colon" are not variables. They are a particular type of string, called a symbol, that is immutable and optimized for quick identification by the interpreter, in fact, those are stored internally as pointers, so that :this == :this is a very quick operation.

This property makes them good candidates for hash keys because they offer quick retrieval or for "flags" to pass to a method; Think of them as a sort of loose constant that "stands for" what they say. Their immutability is also dangerous: All symbols ever created never get garbage collected; It's easy to create a memory-leak by creating thousands of symbols, so use them wisely.

UPDATE since ruby 2.2 symbols may be garbage-collected in certain cases (when no reference is kept and no comparison is needed)

stonedauwg
  • 1,328
  • 1
  • 14
  • 35
m_x
  • 12,357
  • 7
  • 46
  • 60
  • 1
    Your dire warnings about class variables and symbols only really apply to careless use. Abuse of anything in programming can lead to problems; Abusing symbols can lead to excessive memory consumption, but normal code won't have the problem, it'd take dynamically creating them in an unusual situation to cause that. Using class variables needs to be done carefully, and their existence is often a red-flag that variable scoping is being abused, but they also make it possible to share variable state between instances of an object cleanly. We always have to know what we're doing or chaos happens. – the Tin Man Nov 04 '13 at 16:05
  • I don't know why the -1, but I suspect it's because of what I commented on above. – the Tin Man Nov 04 '13 at 16:06
3

Variables with an @ symbol are instance variables. What this means is that they persist as long as the instance of the class they are declared in persists. So if you have a class called Message and each message has a variable called @subject, when you instantiate a new message it will keep that subject variable in memory as long as the message object itself lives. Now if it did not have the @ symbol, once the function it was declared in "went out of scope" aka finished, the variable would be "lost" as the function was complete and the memory was reclaimed by the Ruby VM. There are also "class variables" that are prefaced with two @ symbols. This means the variable is shared across all instances of a class.

As for the colon, if it is before a variable that means it is a "symbol", which is usually used as an identifer for hashes and other bits of data in Ruby. If it is at the end of a word that means it is the key portion of a hash identifier in Ruby 1.9+ syntax.

MattC
  • 12,285
  • 10
  • 54
  • 78
  • 4
    For the sake of completeness, if the colon is at the end of a word, it's the key portion of a hash *and* is a symbol. – colinm Nov 04 '13 at 16:39
2

sometimes have variables with the "@" symbol in front of them, and then some variables do not have the @ symbol in front of them.

Variables with the "@" symbol are instance variables,which are not preceded by @,can be constants or local variables or global variables. Read Ruby Programming/Syntax/Variables and Constants.

Sometimes I see variables where the colon is in the front, such as :order

They are called symbols.

and then I see variables where the colon is at the end, such as colon:. I do not understand what the colon is doing.

These probably the Hash syntax(as you give us hints,so I would guess),where keys are symbols. Example : {foo: 1} - this is a Hash.

Also read as you requested :

Community
  • 1
  • 1
Arup Rakshit
  • 116,827
  • 30
  • 260
  • 317
  • What are the differences between instance variables, local variables and global variables? What are instance variables used for? – Sameer Anand Nov 04 '13 at 15:21
  • @SameerAnand You should spend some time reading about object oriented theory, and variable scope. These are not ruby-specific concepts. – Michael Berkowski Nov 04 '13 at 15:22
  • I know all about Object Oriented programming, I use Java all of the time. However, I am having trouble moving over to Ruby on Rails because the syntax is completely different, Rails is something completely new to me, and Web Development is something I never did in Java. – Sameer Anand Nov 04 '13 at 15:25
  • @SameerAnand Then you know what instance variables are, and the differences between locals, globals, and instance variables. The syntax and precise semantics are covered in most any Ruby programming guide. In Rails, instance variables are also used to transfer data to the view layer. – Dave Newton Nov 04 '13 at 15:36
2

Instance Variables: (@foo = '123') An instance variable is defined and keeps its value throughout the current instance of the request. In the rails mvc paradigm, the most common use of instance variables are used to help communicate data from the controller to the view, and allows you ro define things in one part of the controller and use in another.

class ProjectsController < ApplicationController
  before_filter :find_project

  def show; end

  def update
    if @project.update_attributes(params[:project])
      ...
    end
  end

  private
  def find_project
    @project = Project.find(params[:id])
  end
end

In the above code, you can see that there is a before filter that gets ran before every method. In the above case, we find the current project and save it to an instance variable. And because its an instance method, its able to be access anywhere within this class as well as the views used to render the html.

Local Variables: (foo = '123') Pretty much exactly what the name implies, they are only able to be accessed within the current method (def) of where they are defined.

Michael Lynch
  • 1,743
  • 15
  • 27