-
-
Save feliperaul/372bf2732509f3eea1cff9c7a06d7718 to your computer and use it in GitHub Desktop.
Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Greeter | |
def greet(name) | |
"Hello #{name}" | |
end | |
end | |
class User | |
def first_name | |
"Foo" | |
end | |
def greet_with(&block) | |
Greeter.new.instance_exec(&block) | |
end | |
def greet_first_name | |
greet_with { greet(first_name) } | |
end | |
end | |
User.new.greet_first_name |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The problem here is that
greet(first_name)
is actually callinggreet(self.first_name)
, and inside theinstance_exec
block, theself
is no longerUser
. The block scope still sees local variables - it just can't run the method. So one solution is just putting the result of the method in a local var:instance_exec
actually has a built-in pattern for this. It takes arguments which it will pass to the block. This is useful if you want to use methods or instance variables, without needing to put them into local variables. We just need to adjust thegreet_with
method a little:This way you can be more explicit about the original lexical scope you're using.
Neither is particularly pretty, but it's not a particularly common scenario either.