Ruby 1.9.2:如何更改块的范围/绑定



嗨,我有类似的东西:

class TrialRequest
  attr_accessor :trial_email
  def initialize(email)
    @trial_email = email
    puts "Trial_email: #{trial_email}"
  end
  def create
    @email = ::Gmail.connect!(gmail_name, gmail_password) do |gmail|
      email = gmail.compose do
        to 'trial@domain.com'
        from trial_email
        subject trial_email
        text_part do
          content_type 'text/html; charset=UTF-8'
          body 'Sign me up.'
        end
      end
      #binding.pry
      gmail.deliver!(email)
    end
  end
end

问题是在撰写块内部未定义trial_email

NameError: undefined local variable or method `trial_email' for #<Mail::Message:0x0000000431b830>

这是 Ruby 1.9 问题还是 gmail gem 问题?

我应该如何使此方法"可见"/在撰写块的范围内?

更新:这是 gmail gem 的一个问题/功能 - Ruby 1.9 块已经改变,但没有那么大变化!除了接受的答案之外,另一种解决方法是将数据作为方法参数传入:

def create(trial_email)
  ...
end
对我来说

看起来像一个 GMail 问题。在方块中,self将是来自GMail宝石的一些对象,以便您可以获得tofrom和类似的DSL细节。您应该能够将self.trial_email放入局部变量中,然后在块中访问它:

email_address = self.trial_email
@email = ::Gmail.connect!(gmail_name, gmail_password) do |gmail|
  email = gmail.compose do
    to 'trial@domain.com'
    from email_address
    subject email_address
    #...

> 你期望(正如你有权的那样(块应该像往常一样保留自我的价值。看起来 gmail gem 在这里使用了 instance_exec,它允许它将块的 self 值更改为 Mail::Message 的实例(这就是为什么即使您没有定义此类方法,您也可以在该块中调用 tofrom(

虽然instance_exec对于生成漂亮的DSL很方便,但它并非没有缺点。局部变量范围不受影响,因此您可以在块之前将trial_emailself存储在局部变量中,然后在块内使用该局部变量

问题是你传递给compose方法的块后来传递给Mail.new,最后传递给Message.new(如果我正确跟踪链(,然后这个块在这里像这样计算:

instance_eval(&block)

由于它是在不同对象(Message类的实例(的方法initialize执行的,因此您无权访问TrialRequest对象的属性。

您可以做同样的事情而不会遇到这样的麻烦:

email = gmail.compose
email.to = 'trial@domain.com'
email.from = trial_email
email.subject = trial_email
email.text_part do
  content_type 'text/html; charset=UTF-8'
  body 'Sign me up.'
end

相关内容

  • 没有找到相关文章

最新更新