Q: When do I use the at-sign (@), the colon (:) and just the variable name in rspec / rails? I have finished Hartl's Rails Tutorial and one area of confusion still reigns: when do I use @variable, when should I use :variable, and when is just variable correct?
Here is some example code I took from the tutorial:
describe "micropost associations" do
    before { @user.save }
    let!(:older_micropost) do 
      FactoryGirl.create(:micropost, user: @user, created_at: 1.day.ago)
    end
    let!(:newer_micropost) do
      FactoryGirl.create(:micropost, user: @user, created_at: 1.hour.ago)
    end
    .
    .
    .
    it "should destroy associated microposts" do
      microposts = @user.microposts.dup
      @user.destroy
      microposts.should_not be_empty
      microposts.each do |micropost|
        Micropost.find_by_id(micropost.id).should be_nil
      end
    end
  end
  .
  .
  .
end

As compared to:
describe Micropost do
  let(:user) { FactoryGirl.create(:user) }
  before { @micropost = user.microposts.build(content: "Lorem ipsum") }

Here are some more specific questions that this (and other code) raises for me:


*

*Does @user need the @ in the first snippet because it's the subject or..?

*Do I always declare new variables using :? (Actually I'm fairly sure this isn't the case but I don't understand there whys and wherefores.)

*When I refer later to a variable I created using :, do I use : again?  For example if I were to execute print(:older_micropost) or print(older_micropost), is there a difference? (See the let statement in the second snippet).

*Do they all work the same within a before block as outside one?  I am finding that some code will only work inside / outside a before block (eg older_micropost.destroy).


I have looked elsewhere for the answer to this but I can't find a discussion of all three of @, :, and nothing.
Edit: here's a third snippet of code, this time my own.  I've commented what works and what doesn't:
describe "deleting a user following" do
  let(:userid) { @user.id }
  before { print(@user.id.inspect) # this works
           @user.destroy }         # this works
  @user.destroy                    # this doesn't
  print(@user.id.inspect)          # this doesn't
  subject { other_user }
  its(:followed_users) { should_not include(userid) }
end

(Obviously I don't run all 4 lines of commented code together, I run the two inside the before block OR the two outside)
Why do those statements only work inside a before block?

A: He's mixing the old and new RSpec syntax, which makes it somewhat confusing.
The original incarnation of RSpec used instance variables throughout. So:
before { @user = User.new }

it "should be valid" do
  @user.should be_valid
end

RSpec later gained the ability to assign values to variables using let:
let(:user) { User.new }

it "should be valid" do
  user.should be_valid
end

let takes a symbol as an argument and defines a method that yields the specified result when the method is referenced. The main advantage of let is that it is lazy-evaluated. This lets you defer the variable setting, which works particularly well when nesting examples. 
You can mix and match the two paradigms, as Hartl does, but this can become confusing. It's best to use one style or the other.

Does @user need the @ in the first snippet because it's the subject
  or..?

It needs to be defined with @ or without (using let) and then always referred to the same way. @user and user are not the same thing.

Do I always declare new variables using :? (Actually I'm fairly sure
  this isn't the case but I don't understand there whys and wherefores.)

The : is a prefix for a symbol. You would only use it within let.

When I refer later to a variable I created using :, do I use : again?
  For example if I were to execute print(:older_micropost) or
  print(older_micropost), is there a difference? (See the let statement
  in the second snippet).

You use the method name, not the symbol, when referring to a variable. So micropost, not :micropost.

Do they all work the same within a before block as outside one? I am
  finding that some code will only work inside / outside a before block
  (eg older_micropost.destroy).

Any code that works in an example body should also work in a before block. What will not work is placing code outside an example, eg:
let(:user) { User.new(:name => "Phil") }

before { puts user.name } # "Phil"

it "sets the name" do
  puts user.name # "Phil"
end

puts user.name # undefined local variable or method `user' 


A: This is an instance variable, means whenever you need to pass information from controller to views or vice versa we usually usse this @variable
Now : is used for symbols, means they are most of the time similar to strings but they are cheaper than simple strings in terms of memory as it compares the whole string at once.
For more information regarding this, read the article http://www.robertsosinski.com/2009/01/11/the-difference-between-ruby-symbols-and-strings/
