【问题标题】:How do I call all instance methods of a class wIth names starting with a given string?如何调用名称以给定字符串开头的类的所有实例方法?
【发布时间】:2013-09-18 12:26:18
【问题描述】:

我有一个简单的验证类:

class MappingValidator

    def validate(mapping)

    end

    protected

    def validate_presence_of_title(mapping)
      ...
    end

    def validate_presence_of_key(mapping)
      ...
    end

    def validates_class_exists(mapping)
      ...
    end

  end

validate 方法中,我想调用任何以validate_ 开头的方法,并将mapping 作为参数传递。这也需要对MappingValidator 的子类起作用,因此如果子类声明了一个以validate_ 开头的方法,那么在子类实例上调用 validate 时也会调用它。调用顺序无关紧要。

【问题讨论】:

  • 不包含ActiveModel::Validations的任何理由
  • @firien 我没有使用 Rails,这是一个非常具体的用例。
  • 你不需要rails,只需要active_model gem,虽然我认为这取决于active_support(这可能是一个矫枉过正)

标签: ruby dynamic methods metaprogramming


【解决方案1】:

这是怎么回事?

class MappingValidator

    def validate(mapping)
       self.methods.grep(/^validate_/).each do |m|
         send(m,mapping)
       end
    end

    protected

    def validate_presence_of_title(mapping)
      p "1"
    end

    def validate_presence_of_key(mapping)
      p "2"
    end

    def validates_class_exists(mapping)
      p "3"
    end

end

MappingValidator.new.validate("validate_")
# >> "1"
# >> "2"

【讨论】:

    【解决方案2】:

    应该很简单:

    methods.filter {|m| m.to_s.start_with? 'validate_'}.each {|m| send m, mapping}
    

    【讨论】:

    • 我可能会使用methods(false)methods - Object.methods 来删除祖先和/或对象的方法。
    • @theTinMan 但是 OP 说,他/她想从子类访问超类,如果有的话。那么为什么false
    猜你喜欢
    • 2017-12-27
    • 2016-06-05
    • 2015-07-04
    • 1970-01-01
    • 2014-03-29
    • 2010-12-22
    • 2010-09-05
    • 1970-01-01
    相关资源
    最近更新 更多