简体   繁体   English

Ruby,将方法名称作为参数,然后将其发送给对象

[英]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. 我知道应该有一些简单而纯粹的Ruby魔术。

Try Object#public_send : 试试Object#public_send

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

In Ruby, method calls are just messages sent to the object. 在Ruby中,方法调用只是发送给对象的消息。

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 这可能是测试所需要的,但是如果您希望它对于私有方法失败,则只需使用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__ 如果您可能已在该对象上定义了现有的send方法, __send__ send替换为__send__

See https://ruby-doc.org/core-2.5.1/Object.html#method-i-send for more information 有关更多信息,请参见https://ruby-doc.org/core-2.5.1/Object.html#method-i-send

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM