John Feminella
John Feminella

Reputation: 311536

How do I give one method invoked in a block the ability to see variables set in the context of the calling function?

I have a module that defines a method, logged, which will add a prefix to the result of a different method, say:

module M
  def logged(&block)
    str = "logged: "
    block.call
  end

  def say(value)
    puts str + value
  end
end

I'd like to be able to use M inside the body of a class block, like so:

class C
  extend M

  logged {
    say "one"
    say "two"
  }
end

and get:

# => "logged: one"
# => "logged: two"

Essentially, I want say to be able to access values in logged that are only in logged's calling context. So, I'd prefer to avoid instance variables, global variables, et cetera.

What's the right way to pull this off?

Upvotes: 2

Views: 44

Answers (1)

Arup Rakshit
Arup Rakshit

Reputation: 118271

Here is one way to do this :-

module M
  def logged(&block)
    str = "logged: "
    block.call(str)
  end

  def say(str, value)
    puts str + value
  end
end

class C
  extend M

  logged { |s|
    say s, "one"
    say s, "two"
  }
end

Upvotes: 3

Related Questions