From: Bill Kelly Date: 2002-12-27T20:46:35+09:00 Subject: Re: viral arguments Hi, From: "Tom Sawyer" > > the idea is that rather then pass simple argumments, one could pass a little > piece of code that would execute in the context of the method. > > here's a foo example (vproc is like proc but viral): > > def foo(x) > i = 1 > puts "#{x + i}" > end > > puts foo(4) --> 5 > puts foo(vproc {i + 1}) --> 3 > > any thoughts? can ruby achieve something like this already? I did something that sounds a little like that the other day when making a web site for my girlfriend ( http://zip.to/beadyourselfup :) # # Adding a new instance method to String class which "re evaluates" # the string in the context of the Kernel::binding object we pass in. # (Note that the here-document approach this uses tacks on an extra # \n to the resulting string.... but that was fine for my purposes.) # class String def reeval(b = TOPLEVEL_BINDING) eval(%Q{<<"END_REEVAL"\n} + self + "\nEND_REEVAL\n", b) end end class BeadShot # ... def gen_fullsize_html(prev_shot, next_shot) # # Here, a string containing the HTML template for the # page we're generating is "reevaluated" in the current # context - so it has access (via interpolation #{ }) to # the current BeadShot instance's methods, and even the # local variables in scope at the moment (prev_shot, # next_shot). # html = $bead_fullsize_page.reeval(binding) end def item_number @file_num + $item_number_offset end # ... etc. end # # Here's an excerpt from the string reevaluated by the code # above. Note that I wanted interpolation to occur both when # the string was defined - to pull in other components of the # page like $header_html - and later when re-evaluated; so # the interpolation that's deferred for "reeval" is escaped # like \#{ } . # $bead_fullsize_page = <<"END_HTML" #$header_html
item # \#{ item_number }
\#{ gen_fullsize_inline_img(1) }
\#{ prev_shot ? prev_shot.gen_link("previous", 1) : "" } \#{ (prev_shot && next_shot)? $sep_bar : "" } \#{ next_shot ? next_shot.gen_link("next", 1) : "" }
 
... back to home page ...
END_HTML An example of the resulting HTML can be seen at the bottom of: http://www.foosenblat.com/beadyourselfup/bead_html/bead00057.html [Flames about anything stupid I may have done in the HTML that aren't Ruby-related should probably be sent to me off-list. ] Anyway I wondered if this might be similar to what you had in mind with "viral arguments". ? Regards, Bill