2011-10-28 48 views
7

我是新來的紅寶石,不知道爲什麼我在這種情況下使用一個簡單的應用程序西納特拉的「郵件」寶石得到一個錯誤:爲什麼Mail塊不能看到我的變量?

post "/email/send" do 

    @recipient = params[:email] 

    Mail.deliver do 
    to @recipient # throws error as this is undefined 
    from '[email protected]' 
    subject 'testing sendmail' 
    body 'testing sendmail' 
    end 

    erb :email_sent 

end 

然而,這工作得很好:

post "/email/send" do 

    Mail.deliver do 
    to '[email protected]' 
    from '[email protected]' 
    subject 'testing sendmail' 
    body 'testing sendmail' 
    end 

    erb :email_sent 

end 

我懷疑這與塊的範圍和我對它的誤解有關。

+1

你確定你的問題是與實例var,而不是'params [:email]'?你嘗試過輸出嗎?在這裏也應該有一個局部變量,因爲塊無論如何都是關閉的。 –

回答

14

由於Julik說,Mail#delivery執行使用#instance_exec你的塊,它只是改變self同時運行的塊(你將無法以其他方式調用方法#to#from塊內)。

你真的可以在這裏做的是使用一個事實,即塊是關閉。這意味着它「記住」周圍的所有局部變量。

recipient = params[:email] 
Mail.deliver do 
    to recipient # 'recipient' is a local variable, not a method, not an instance variable 
... 
end 

再次,簡要地:

  • 實例變量和方法調用取決於self
  • #instance_exec改變self;
  • 局部變量不依賴於self並且被塊記住,因爲塊是關閉
+0

另外還有一點:這種行爲不依賴於Ruby的一個版本。所以我會從問題標題中刪除「Ruby 1.9」這個詞,這可能會讓人感到困惑。 –

+0

所以我的錯誤是使用實例變量?我使用了一個實例變量,因爲我想要在ERB模板中提供這些數據,並且 - 如果我沒有弄錯 - 這意味着它需要是一個實例var。我可以通過聲明一個局部變量或者使用Tin Man建議的一種方法來解決這個問題。謝謝,到目前爲止愛Ruby,但很多要學習:) –

3

我認爲這是因爲郵件寶石使用instance_execinstance_exec使用來自調用者的對象的實例變量,而不是來自調用者的實例變量。我要做的是在Mail gem中找到一個不使用實例技巧但將顯式配置對象傳遞給該塊的方法,並從那裏繼續。備用一些灰色頭髮。

8

如果您將通過Mail的文檔進一步閱讀,你會發現一個很好的替代解決方案,將工作。而不是使用:

Mail.deliver do 
    to @recipient # throws error as this is undefined 
    from '[email protected]' 
    subject 'testing sendmail' 
    body 'testing sendmail' 
end 

可以使用郵件的new()方法,傳遞參數,並忽略塊:

Mail.new(
    to:  @recipient, 
    from: '[email protected]', 
    subject: 'testing sendmail', 
    body: 'testing sendmail' 
).deliver! 

或備選哈希元素定義:

Mail.new(
    :to  => @recipient, 
    :from => '[email protected]', 
    :subject => 'testing sendmail', 
    :body => 'testing sendmail' 
).deliver! 

在撬,或irb你會看到:

pry(main)> Mail.new(
pry(main)* to: '[email protected]', 
pry(main)* from: '[email protected]' << `hostname`.strip, 
pry(main)* subject: 'test mail gem', 
pry(main)* body: 'this is only a test' 
pry(main)*).deliver! 
=> #<Mail::Message:59273220, Multipart: false, Headers: <Date: Fri, 28 Oct 2011 09:01:14 -0700>, <From: [email protected]>, <To: [email protected]>, <Message-ID: <[email protected]>>, <Subject: test mail gem>, <Mime-Version: 1.0>, <Content-Type: text/plain>, <Content-Transfer-Encoding: 7bit>> 

new方法有多種可供使用的變體。這是從文檔還,而且可能效果更好:

作爲一個側面說明,你也可以創建一個新的電子郵件,通過直接創建郵件:: Message對象,然後通過串,符號或直接在價值傳遞方法調用。有關更多信息,請參閱Mail :: Message。

mail = Mail.new 
mail.to = '[email protected]' 
mail[:from] = '[email protected]' 
mail['subject'] = 'This is an email' 
mail.body = 'This is the body' 

其次mail.deliver!

另請注意,在前面的示例中,有多種方式可以訪問郵件信封中的各種標題。這是一個靈活的寶石,似乎被深思熟慮,很好地遵循Ruby的方式。

+0

感謝您爲我做這項研究:)我一直在尋找GitHub文檔太緊密,而不是去看RubyGems的。在那裏學到的經驗再次感謝。 –

相關問題