RJS callback functions fun

I was struck by the fact that there doesn’t seem to be a way to use RJS
to install a callback. For example:

page.visual_effect :slideup, @dom_id, :afterFinish => XXXXX

I want the XXXXX to be more RJS code. I don’t want to have to revert
back to Javascript! But that seems the only solution. What if I have a
bunch of DOM manipulation I have do after I have slide the area up? What
I want is something like:

page.visual_effect :slideup, @dom_id, :afterFinish => page.function {|p|
p.replace_html ‘foo’, ‘Bar’
p.show ‘baz’
}

So I took a stab at implementing Javascript functions via RJS. The below
implementation allows you to define a anonymous function which is
returned as a string. Or you can give the function a name (and possible
some argument names) and you get to define a named function (although I
haven’t really tested this as I really only need anonymous functions for
callbacks). I welcome feedback and hope this is useful to someone else.

module ActionView
module Helpers
module PrototypeHelper
class JavaScriptGenerator
module GeneratorMethods
# Will create a function using the block as the defination for the
# function. If the function is given a name then it will be
recorded
# to the page under the name given. If a name is not given then
# an anonymous function is instead created as a string and
returned.
# nothing is recorded to the page. This allows your function to be
# used as a callback such as in :after_finish on a visual_effect.
def function(name=nil, *arg_names, &blk)

 # Run block to collect lines
 sub_gen = JavaScriptGenerator.new @context, &blk
 body = sub_gen.instance_variable_get("@lines") * ";#{$/}\t"

 # For line from block execution
 line = "function #{name}(#{arg_names.collect(&:to_s).join ', '
}) {#{$/}\t#{body}#{$/}}"

 name ? record(line) : line

end
end
end
end
end
end