Check whether method named in a string is defined before calling it with send

倖福魔咒の 提交于 2021-01-29 16:00:46

问题


#!/usr/bin/env ruby

def say_hi
    puts 'hi'
end

greeting = 'say_hi'
send greeting # works

greeting = 'say_hix'
send greeting # undefined method `say_hix' for main:Object (NoMethodError)

Thus in case of a typo I want to first check if the method exists; something like:

send greeting if greeting.is_a_method

回答1:


You can use respond_to?

Returns true if obj responds to the given method. Private and protected methods are included in the search only if the optional second parameter evaluates to true.

respond_to?(greeting)

respond_to? does not work.

I've tried the following with IRB, and it works fine:

2.6.3 :001 > def say_hi
2.6.3 :002?>       puts 'hi'
2.6.3 :003?>   end
 => :say_hi 
2.6.3 :004 > greeting = 'say_hi'
 => "say_hi" 
2.6.3 :005 > send greeting if respond_to?(greeting) 
hi
 => nil 
2.6.3 :006 > greeting = 'say_hix'
 => "say_hix" 
2.6.3 :007 > send greeting if respond_to?(greeting)
 => nil 

Could you please try it in a file?

As the documentation says, respond_to? includes private and protected methods only if you pass a second optional parameter and it evaluates to true. Since say_hi is a private method, you need to pass in the second optional parameter:

def say_hi
    puts 'hi'
end

greeting = 'say_hi'
send(greeting) if respond_to?(greeting, true) 

greeting = 'say_hix'
send(greeting) if respond_to?(greeting, true)


来源:https://stackoverflow.com/questions/61927012/check-whether-method-named-in-a-string-is-defined-before-calling-it-with-send

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!