ruby lazy私有方法

时间:2014-01-14 03:07:21

标签: ruby ruby-1.9.3 activemodel ruby-2.0

我有一个班级:

class Validator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    unless valid?(value)
      record.errors.add(attribute, attribute.to_sym, options.merge(value: value))
    end
  end
end

我有大量的子类(只有私有valid?方法),即

class KppValidator < Validator
  private

  def valid?(kpp)
    kpp.size == 9
  end
end

有没有办法避免在每个有效之前写private?后代类中的方法?

我试图在类Validator中编写'private:valid?',但得到异常no such method 'valid?'

我能做什么?

2 个答案:

答案 0 :(得分:2)

我认为你的整个方法在Ruby上下文中有点奇怪。更Rubyish和Railsy的方法是编写宏,然后在子类中使用块而不是私有方法。

这样的事情:

class Validator < ActiveModel::EachValidator
  def self.validate_using(&block)
    define_method :validate_each do |record, attribute, value|
      unless block[value]
        record.errors.add(attribute, attribute.to_sym, options.merge(value: value))
      end
    end
  end
end

class KppValidator < Validator
  validate_using { |kpp| kpp.size == 9 }
end

由于这定义了整个validate_each方法,这甚至可以在验证期间为您节省一个方法调用(在初始化所有内容时,只需花费一些额外的工作费用)。

我不知道这对十个验证员来说是否值得,我会把它留给你。

答案 1 :(得分:0)

如果您想为后续方法转回private,则单独编写public可能会很不方便。相反,你可以尝试:

class KppValidator < Validator
  def valid?(kpp)
    kpp.size == 9
  end
  private :valid?
end

从Ruby 2.1.0开始def将方法名称作为符号返回,因此您可以将其简化为:

class KppValidator < Validator
  private def valid?(kpp)
    kpp.size == 9
  end
end

但你是对的,即使你要将valid?定义为基类中的私有方法,当你重新定义它时它将在子类中变为公共,除非你明确地将它设为私有。 / p>

相关问题