我在这里缺少一些基本的Ruby变量范围知识。 我尝试使用Mail发送电子邮件(这是我的生产脚本的简化版本,但它可以显示问题):
#!/usr/bin/ruby
require 'rubygems'
require 'mail'
@final_file=File.new("/usr/shared/name/ruby/file2.html","w")
@final_file.write("foo-bar")
puts @final_file.path
Mail.defaults do
delivery_method :smtp,{ :address => 'localhost', :port => 25,:openssl_verify_mode => OpenSSL::SSL::VERIFY_NONE}
end
mail = Mail.new do
from 'me@somehost.net'
to 'mymail@mydomain.com'
subject 'Some subject'
body "here the body"
add_file :filename => 'filename.html', :content => File.read(@final_file.path)
end
mail.deliver!
我得到的输出是:
/usr/shared/name/ruby/file2.html
email2.rb:19: warning: instance variable @final_file not initialized
email2.rb:19:in `block in <main>': undefined method `path' for nil:NilClass (NoMethodError)
from /usr/lib64/ruby/gems/1.9.1/gems/mail-2.5.4/lib/mail/message.rb:132:in `instance_eval'
from /usr/lib64/ruby/gems/1.9.1/gems/mail-2.5.4/lib/mail/message.rb:132:in `initialize'
from /usr/lib64/ruby/gems/1.9.1/gems/mail-2.5.4/lib/mail/mail.rb:50:in `new'
from /usr/lib64/ruby/gems/1.9.1/gems/mail-2.5.4/lib/mail/mail.rb:50:in `new'
from email2.rb:14:in `<main>'
因此,首先创建文件并填充一些文本,然后puts
命令按预期打印文件的路径,但出于某种原因,在邮件变量声明之后,{{ 1}}变量设置为@final_file
,我无法弄清楚这里发生了什么,似乎垃圾收集器正在摆脱该变量。
答案 0 :(得分:2)
您看到的是因为block
内的Mail.new
与@final_file
的范围不同,因为代码calls:
if block_given?
instance_eval(&block)
end
这意味着该块是从 Mail
范围内的运行的。这使您可以调用from
和to
等方法。
据我从代码中理解,您可以将参数传递给初始化程序,如下所示:
mail = Mail.new(final_path: @final_file.path) do
from 'me@somehost.net'
to 'mymail@mydomain.com'
subject 'Some subject'
body "here the body"
add_file :filename => 'filename.html', :content => File.read(self[:final_path])
end
(这是未经测试的,因此所需的语法可能会略有不同)。