具有哈希参数的Ruby public_send方法(如果适用)

arj*_*jun 1 ruby methods

Tldr:我试图使用public_send来调用方法,但其中一些方法也需要参数.如何检查哪些需要参数并将其作为参数添加并将其包含在调用中

我在这样的类中有一系列方法
class_methods = [:first, :second, :third, :fourth] ...

我定义了一个can_execute方法来检查类是否有方法,如果是,它将执行.

def can_execute (class, method_name)
  if class.respond_to?(method_name.to_sym) && class.class_methods.include?(method_name.to_sym)
    class.public_send(method_name)
  end
end
Run Code Online (Sandbox Code Playgroud)

当用户提供任何这些class_method作为参数时,我可以这样称呼它们
can_execute(class, method_name)

问题是这些方法中的一些接受散列作为参数,如
class.first(Value: true)
class.second(Id: 0, Value: "string")

但有些不
class.third

我不确定如何包含其中一些class_methods需要的params哈希?

我可以通过调用method_args它们 来检查这些方法需要哪些参数

class.method_args(:first)
-> [:Value]

class.method_args(:second)
=> [:Id, :Value]

class.method_args(:third)
=> []
Run Code Online (Sandbox Code Playgroud)

iCo*_*ime 5

您需要传递参数,can_execute以便将它们传递给public_send.splat运营商是你的朋友.当用作参数时,它将使用它的名称将任意数量的参数包装到数组中.在数组上使用时,它会将数组分解为参数以传递给方法.

除此之外,class还有关键字.惯例是调用它klass,但它可以是你想要的任何东西(除了类)

考虑到这一点,我们的新方法如下所示:

def can_execute (klass, method_name, *args)
  if klass.respond_to?(method_name.to_sym) && klass.class_methods.include?(method_name.to_sym)
    klass.public_send(method_name, *args)
  end
end
Run Code Online (Sandbox Code Playgroud)

然后调用,它可以有参数或不.无需先检查:

can_execute('teststring', :slice, 1, 5) # => "ests"
can_execute('teststring', :upcase) # => "TESTSTRING"
Run Code Online (Sandbox Code Playgroud)

如果您有其他理由要检查参数,可以使用Method#arityMethod#parameters.有这样的结果#slice

klass.method(method_name.to_sym).arity # => -1
klass.method(method_name.to_sym).parameters # => [[:rest]]
Run Code Online (Sandbox Code Playgroud)