代码之家  ›  专栏  ›  技术社区  ›  arjun

ruby public_send方法,在适用的情况下使用散列参数

  •  1
  • arjun  · 技术社区  · 6 年前

    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
    

    当用户提供任何 class_method 作为争论,我可以这样称呼他们
    can_execute(class, method_name)

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

    但有些人没有
    class.third

    我不知道如何包含这些参数散列 class_methods 要求?

    我可以通过调用 method_args 在他们身上,就像

    class.method_args(:first)
    -> [:Value]
    
    class.method_args(:second)
    => [:Id, :Value]
    
    class.method_args(:third)
    => []
    
    1 回复  |  直到 6 年前
        1
  •  5
  •   iCodeSometime Francesca    6 年前

    你需要把论点传给 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
    

    然后调用,它可以有参数也可以没有。无需先检查:

    can_execute('teststring', :slice, 1, 5) # => "ests"
    can_execute('teststring', :upcase) # => "TESTSTRING"
    

    如果有其他原因要检查参数,可以使用 Method#arity Method#parameters . 像这样的结果 #slice

    klass.method(method_name.to_sym).arity # => -1
    klass.method(method_name.to_sym).parameters # => [[:rest]]