mardi 27 juin 2017

Create method dynamically, including dynamic but fixed argument list, with define_method in ruby?

How do I create a method dynamically with a fixed list of arguments determined at runtime by an array of symbols, or a fixed hash of named parameters?

Statically, I write

 def foo(bar,baz)
   [bar,baz]
 end

 foo(1,2) #=>[1,2]
 foo(1,2,3) #=> ArgumentError: wrong number of arguments (given 3, expected 2)

Now I want to create this method at runtime. According to define_method: How to dynamically create methods with arguments we can just

 define_method(:foo) do |bar,baz|
   [bar,baz]
 end

 foo(1,2) #=> [1,2]
 foo(1,2,3) #=> ArgumentError: wrong number of arguments (given 3, expected 2)

But that only works if I know the argument list when writing the method. What if only have the argument list at runtime? At How do you pass arguments to define_method? it is suggested we can use the splat operator to accept any array of arguments:

 define_method(:foo) do |*args|
   args
 end

 foo(1,2) #=> [1,2]
 foo(1,2,3) #=> [1,2,3]

But can we fix the allowed arguments to conform to a list of arguments given at runtime, duplicate the static code, so that the following happens?

 arr = [:bar,:baz]

 define_method(:foo) do |*args=arr| #or some other magic here
   args
 end

 foo(1,2) #=> [1,2]
 foo(1,2,3) #=> ArgumentError: wrong number of arguments (given 3, expected 2)





Aucun commentaire:

Enregistrer un commentaire