2013-02-14 27 views
3

我已經完成哈特爾的Rails的教程和混亂的一個領域仍然居於主導:我什麼時候使用@variable,當我應該使用:variable,當只是variable正確的嗎?何時使用at符號(@),冒號(:)和rspec/rails中的變量名?

下面是一些示例代碼,我從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 

相比於:

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

以下是這(和其他代碼)提出了我一些更具體的問題:

  1. 是否@user需要@在第一個片段,因爲它的詞典定義。他主題還是..??
  2. 我是否總是使用:來聲明新變量? (實際上我相當確定情況並非如此,但我不明白那裏是什麼,因此我不明白。)
  3. 當我後面提到使用:創建的變量時,是否再次使用:?例如,如果我要執行print(:older_micropost)print(older_micropost),是否有區別? (請參閱第二個片段中的let聲明)。
  4. 難道他們作爲全部工作的before塊作爲外部的一個內一樣嗎?我發現有些代碼只能在before塊內部/外部工作(例如older_micropost.destroy)。

我已經尋找其他地方的答案,但我找不到@,:,而且沒有任何討論。

編輯:這裏的第三個代碼段,這段時間我自己。我評論什麼可行,什麼不可行:

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 

(很顯然,我不運行所有4行註釋代碼在一起,我跑了兩個內線塊之前或兩者外)

爲什麼這些語句只能在before塊之前工作?

回答

2

他混合了新老RSpec的語法,這使得它有點混亂。

的RSpec的原始化身使用實例變量貫穿始終。所以:

before { @user = User.new } 

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

RSpec的後獲得了對給變量賦值使用let的能力:

let(:user) { User.new } 

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

let需要一個符號作爲一個參數,並限定其產生規定的結果當該方法被引用的方法。 let的主要優點是它被懶惰評估。這可以讓您推遲變量設置,這在嵌套示例時非常有效。

你可以像Hartl那樣混合和匹配兩種範例,但這會變得令人困惑。最好使用一種風格或其他風格。

請問@user在第一個片段中是否需要@,因爲它是主題 或..?

它需要使用@或不使用(使用let)進行定義,然後始終以相同的方式引用。 @useruser不是一回事。

我是否總是使用以下方法聲明新變量:? (其實我相當肯定 這是不是這樣的,但我不知道有理由和目的。)

的:是一個符號的前綴。您只能在let內使用它。

當我在後面引用我使用創建的變量時,是否再次使用? 例如,如果我要執行print(:older_micropost)或 print(older_micropost),是否有區別? (請參閱第二段中的let語句 )。

引用變量時,使用方法名稱而不是符號。所以micropost,而不是:micropost

他們所有的工作都在一個前面的塊之前是一樣的嗎?我是 發現某些代碼只能在塊 (例如,old_micropost.destroy)之前的內部/外部工作。

在示例主體中工作的任何代碼也應該在before塊中工作。什麼將工作是把代碼的例子外,如:

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' 
+0

這是偉大的,真的有幫助,謝謝!在關於'之前'塊的部分,你有什麼想法爲什麼我的第三個代碼片斷的代碼在'before'塊之外失敗了嗎?一個簡單的例子是「描述」這個工作「在{@ user.destroy}結束與'描述'之前做'這不工作'do @ user.destroy結束' – Lindsayts 2013-02-16 03:26:34

+0

你的代碼需要進入一個示例塊'it'或'specify'),或者一個'before'(或'after')塊。這些塊之外的代碼將在「主要」上下文中運行;示例中的代碼在單獨的上下文中運行,並且可以訪問設置塊中定義的變量和方法。 – zetetic 2013-02-16 06:17:44

1

這是一個實例變量,意味着當你需要通過從控制器的信息,以觀點或反之亦然,我們通常USSE這@variable

現在:將用作符號,表示他們最相似的字符串時但是就內存而言,它們比簡單的字符串便宜,因爲它一次比較整個字符串。

有關更多信息,請閱讀文章http://www.robertsosinski.com/2009/01/11/the-difference-between-ruby-symbols-and-strings/

+0

好,謝謝,我讀了整個事情,但我仍然在'@'我的問題1-4不清楚。我會用更多的代碼更新我的問題,看看是否更清楚 – Lindsayts 2013-02-14 06:44:35

+0

@Lindsayts我將在此期間更新我的答案以及..更多的研究成果的主題:) – swapnesh 2013-02-14 07:43:26