在使用 send 调用之前检查是否定义了字符串中命名的方法

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

#!/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)

因此,如果打错了,我想先检查该方法是否存在;类似于:

send greeting if greeting.is_a_method

您可以使用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.

我用 IRB 尝试了以下方法,效果很好:

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?

如文档所述,respond_to? 仅当您传递第二个可选参数且计算结果为 true 时才包含私有和受保护的方法。由于say_hi是私有方法,所以需要传入第二个可选参数:

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)