Search code examples
rubyblockruby-1.9.2

Ruby 1.9.2: How to change scope/binding of a block


Hi I have something like the folowing:

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 '[email protected]'
        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

The problem is that inside the compose block trial_email is not defined:

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

Is this a Ruby 1.9 issue or a gmail gem issue?

How should I go about making this method 'visible'/within the scope of the compose block?

Update: This is an issue/feature of the gmail gem - ruby 1.9 blocks have changed but not this much! In addition to the accepted answer, another workaround is to pass the data in as a method parameter:

def create(trial_email)
  ...
end

Solution

  • Looks like a GMail issue to me. Inside the blocks, self will be some object from the GMail gem so that you can have to, from, and similar DSL niceties available. You should be able to put self.trial_email into a local variable and then access that inside the blocks:

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