Inject: Temporarily extend the calling scope of a block.
inject can be used to temporarily extend the calling scope of a block with instance methods from a module.
It is written to help Domain Specific Language(DSL) writers to provide a DSL with their own methods without losing the calling scope of the caller. Please check the README if you’re interested, it has some explanation, and rationale.
I’ve had this idea for a while, but took the last hour to write the project, try it out, tell me what you think!
Comments
I think #instance_exec solves this problem, but it might be 1.9 only…
instance_exec can let you pass selected variables from one scope to another it’s true, but it doesn’t solve the problem for DSL writers because you want all of the calling scope available to the caller(user of the DSL).
A approach that does work is:
# Your code(The DSL Writer) def DSL yield DSLProxy.new end
# Caller code (The DSL User) def do_something :rob end
DSL do |proxy| proxy.option do do_something end end </code>
It is the calling scope of the DSL user you want to keep. But we’re trying to achieve:
DSL do option do do_something end end
‘option’ is sent onto DSLProxy, but when the ‘DSL’ method finishes, ‘option’ is removed from the injected module, and calls are sent back to to ‘self’ as it was before the injection (so probably a NoMethodError for this one, but if ‘option’ was defined in the calling scope previously, it’d go back to that method)
Post a comment