I have an object with an instance variable:
obj = Object.new
obj.instance_variable_set :@who, “foo”
I have a proc with arity 1:
@who= “main”
holla = lambda{ |str| p @who, str }
I want to evaluate the lambda inside the scope of obj, but also pass
in a local variable. I can’t figure out how to do this (or if it’s
even possible).
I can’t instance_eval the proc in the context of obj, because the proc
has arity:
obj.instance_eval( &holla )
#=> ArgumentError: wrong number of arguments (0 for 1)
And just invoking the proc within the context of obj doesn’t set the
scope:
obj.instance_eval{ holla[ “hoorah” ] }
#=> “main”
#=> “hoorah”
Any sweet meta trickery you can think of to accomplish what I want?
For those interested in second-guessing my approach and coming up with
a better way to achieve the same end goal, the application is a
documentation system which converts markup (markdown, textile, haml,
etc.) into CHM. I have a system for registering an arbitrary number of
HTML post-processors with the application. The post-processors
associate a regexp with a proc that converts the matched code:
module DocuBot
@snippets = {}
def self.handle_snippet( regexp, &handler )
@snippets[ regexp ] = handler
end
def self.process_snippets( html )
@snippets.inject(html){ |h,(regexp,handler)| h.gsub( regexp,
&handler ) }
end
end
…
Represents an entire documentation site
class DocuBot::Bundle
def write_html
@pages.each do |page|
html = DocuBot.process_snippets( page.to_html )
…
end
end
end
…
Mark $$foo$$ as glossary items.
DocuBot.handle_snippet /$$\w[^$]+$$/ do |match|
# TODO: look up the glossary term in the bundle’s glossary
# and insert appropriate text, or flag a new glossary term
“#{match[2…-3]}”
end
This works fine, except for the TODO above. I want to be able to
instance_eval that block within the scope of a particular bundle so I
can look at @glossary before returning the correct final HTML for gsub
to use.