Ruby Ruby
Ruby Ruby

Reputation: 1

Ruby, take method name as an argument, then message it to an object

what is the best way to create a method with a such behavior?

def foo(arg1, arg2, some_method_name)
  arg1.some_method_name(arg2)
end

I know there should be some Ruby magic, simple and pure.

Upvotes: 0

Views: 66

Answers (3)

kiddorails
kiddorails

Reputation: 13014

Will also suggest to rather have such method where you can supply variable arguments to method

def foo(arg1, method_name, *args)
  arg1.public_send(method_name, *args) # dynamically dispatch the method with the relevant arguments
end
foo("kiddorails", :upcase)        # KIDDORAILS
foo("kiddorails", :gsub, 's', '') # kiddorail

Upvotes: 0

iCodeSometime
iCodeSometime

Reputation: 1643

In Ruby, method calls are just messages sent to the object.

You're looking for

def foo(arg1, arg2, some_method_name)
  arg1.send(some_method_name.to_s, arg2)
end

Note that this method can access both public and private methods of the class; this is probably desired for testing, but if you want it to fail for private methods, just use public_send

def foo(arg1, arg2, some_method_name)
  arg1.public_send(some_method_name.to_s, arg2)
end

If you may have an existing send method defined on that object, just replace send with __send__

See https://ruby-doc.org/core-2.5.1/Object.html#method-i-send for more information

Upvotes: 0

Ursus
Ursus

Reputation: 30056

Try Object#public_send:

def foo(arg1, arg2, some_method_name)
  arg1.public_send(some_method_name, arg2)
end

Upvotes: 4

Related Questions