How to save method signature while wrapping it?

Hello, it would be interesting to automatically destruct hashes into
named method arguments, Ruby has the Method.parameters method:

class A
  def my_method a, b, c = 10; end
  p instance_method(:my_method).parameters
  # ==> [[:req, :a], [:req, :b], [:opt, :c]]
end

So, You can use this method signature to automatically destruct hash
into named arguments, something like this:

A.new.send_with_params :my_method, a: 'a', 'b': 'b'

And it works. But, there’s a problem - all this is broken when You wrap
method (like alias_method_chain or some other way) - the signature of
the original method is losted:

class A
  alias_method :my_method_without_feature, :my_method
  define_method :my_method do |*args|
    my_method_without_feature *args
  end
  p instance_method(:my_method).parameters
  # ==> [[:rest, :args]]
end

So, I’m wondering, maybe there’s some way to wrap method and still
preserve its signature?

Basically attribute names are available (from method.parameters), but I
don’t know how to express named attributes in
block signature, i.e. - how to dynamically write ... do |args[1], args[2], args[3]| instead of ... do |*args| (without eval of course
:slight_smile: ).

Thanks, Alex.
http://petrush.in

P.S. if someone interested how to do :send_with_params here’s full code
and specs (search for send_with_params keyword):
https://github.com/alexeypetrushin/ruby_ext/blob/master/lib/ruby_ext/core/object.rb
https://github.com/alexeypetrushin/ruby_ext/blob/master/spec/core/object_spec.rb

It seems that at morning my mind works better than at evening :). I
believe it can be solved by creating the :original_parameters attribute
on the Method and setting it whenever a method is wrapped.

But, it seems too complicated to be practical.

Alexey P. писал 30.10.2011 22:42:

So, I’m wondering, maybe there’s some way to wrap method and still
preserve its signature?

Basically attribute names are available (from method.parameters), but
I
don’t know how to express named attributes in
block signature, i.e. - how to dynamically write ... do |args[1], args[2], args[3]| instead of ... do |*args| (without eval of
course
:slight_smile: ).

I’d say that in this case `eval’ is fine: the environment is
controlled, and
the code being generated is very deterministic. On any sane
implementstion, after
the parsing step this code will be absolutely equivalent to
“properly”-defined one,
and the parsing delay is negligible.

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs