Как определить такой класс, как ActiveSupport::StringInquirer

Определите класс, который при инициализации строкой, например. 'abc' вернет true, если метод 'abc?' называется на нем. Любой другой метод с завершающим знаком '?' вернет ложь. Все остальные методы без завершающего знака '?' поднимет NoMethodError


person Rajesh Paul    schedule 13.09.2019    source источник


Ответы (3)


Вы можете использовать method_missing для ответа на сообщения, для которых нет метода.

В method_missing мы можем проверить имя метода и, если оно заканчивается на ?, проверить, равно ли оно минус ? строке (self).

При использовании method_missing обычно также определяется respond_to?.

class StringInquirer < String
  private

  def method_missing(method_name, *args, &block)
    if method_name.to_s.end_with?('?')
      self == method_name.to_s.delete('?')
    else
      super
    end
  end

  def respond_to?(method_name, include_private = false)
    method_name.to_s.ends_with('?') || super
  end
end

name = StringInquirer.new('sally')
name.sally? # => true

Обратите внимание, что это чувствительно к регистру.

name.Sally? # => false
person Kris    schedule 13.09.2019

class StringInquirer < String
  def initialize(str)
    define_singleton_method(str + '?') { true }
    super(str)
  end
end

name = StringInquirer.new('sally')
name.sally? # => true
name.kim? # => NoMethodError
name.nil? # => false

Подняв NoMethodError для всех методов, оканчивающихся знаком вопроса, вы потеряете nil? и т. д.

person Kris    schedule 13.09.2019

person    schedule
comment
Хотя этот код может ответить на вопрос, он не дает указаний о том, почему он отвечает на вопрос. Пожалуйста, включите информацию о том, что вы делаете и почему это работает. - person kenlukas; 13.09.2019
comment
Вы определяете метод в классе, поэтому все экземпляры будут иметь определенный метод. NewStrInq.new('abc'); NewStrInq.new('abcc').abc? # => true. Если вы хотите сделать это таким образом, вы хотите определить метод в классе singleton (также известном как призрак). - person Kris; 13.09.2019