[英]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.