问题描述
我是 Ruby 的新手,想知道为什么在这种情况下使用简单的 Sinatra 应用程序中的邮件"gem 会出现错误:
I'm new to Ruby and wondering why I am getting an error in this situation using the 'mail' gem in a simple Sinatra app:
post "/email/send" do
@recipient = params[:email]
Mail.deliver do
to @recipient # throws error as this is undefined
from 'server@domain.com'
subject 'testing sendmail'
body 'testing sendmail'
end
erb :email_sent
end
然而这工作正常:
post "/email/send" do
Mail.deliver do
to 'me@domain.com'
from 'server@domain.com'
subject 'testing sendmail'
body 'testing sendmail'
end
erb :email_sent
end
我怀疑这与块作用域和我对它的误解有关.
I suspect this is something to do with block scope and my misunderstanding of it.
推荐答案
正如 Julik 所说,Mail#delivery
使用 #instance_exec
执行你的块,它只是改变了 self
在运行块时(否则您将无法在块内调用方法 #to
和 #from
).
As Julik says, Mail#delivery
executes your block using #instance_exec
, which simply changes self
while running a block (you wouldn't be able to call methods #to
and #from
inside the block otherwise).
在这里你真正能做的是利用一个事实,即块是闭包.这意味着它记住"了它周围的所有局部变量.
What you really can do here is to use a fact that blocks are closures. Which means that it "remembers" all the local variables around it.
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
并且被块记住,因为块是闭包.
- instance variables and method calls depend on
self
#instance_exec
changes theself
;- local variables don't depend on
self
and are remembered by blocks because blocks are closures.
这篇关于为什么邮件块看不到我的变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!