Как исправить "NoMethodError", когда method_missing определен для данного класса? - PullRequest
0 голосов
/ 03 мая 2019

У меня есть класс RubyCsvRow, который содержит строку файла CSV в хэше. Я использую method_missing, чтобы разрешить использование любого столбца в качестве функции для возврата значения строки в этом столбце. Тем не менее, я получаю ошибку method_missing при запуске я пытаюсь использовать его.

Я не был точно уверен, что происходит, поэтому я заменил вызов на вызов в классе.

m = RubyCsv.new
m.each{|row| puts row.class}

Я отредактировал метод, отсутствующий в RubyCsvRow, чтобы я мог видеть, что происходит при его печати, и видеть имя отсутствующего метода:

def self.method_missing(name, *args, &block)
      puts "Called Method Missing"
      puts name.to_s
end

Возвращение только смутило меня больше.

Called Method Missing
to_ary
RubyCsvRow
Called Method Missing
to_ary
RubyCsvRow

Это вызывает метод отсутствует. Я не знаю, почему он печатает имя как to_ary, которое при поиске я обнаружил this , но я не уверен, когда оно неявно преобразуется или почему.

Я искал вокруг и просмотрел эти ссылки. Этикетки, почему я думал, что они не подходят.

Моя личная переменная определена как: attr_accesssor

Мой метод класса, и я использую его как один

Я вызываю свой метод после определения его

Я не уверен в этом. Я уже конвертирую свой символ в_s, но у меня возникли проблемы с определением, подходит ли это значение

Почему я решил отформатировать каждый метод в RubyCsv так, как я это сделал

class RubyCsvRow
    attr_accessor :values

    def initialize(start)
      @values = start
    end 

    def self.method_missing(name, *args, &block)
      if @values.key?(name.to_s)
        @values[name.to_s]
      else
        puts "No Column with name: ", name.to_s, " found!"
      end
    end

    def to_s
      self.inspect
    end
end

r = RubyCsvRow.new({"one" => "dog", "two" => "cat" })
puts r.one 

RubyCsvRow используется в каждом RubyCsv, но я получаю ту же ошибку только с этим кодом. Я могу опубликовать код RubyCsv, но это минимальный код для воспроизведения ошибки.

Я получаю ошибку NoMethodError для одного вместо печатной собаки.

1 Ответ

0 голосов
/ 03 мая 2019

Попробуйте использовать def method_missing вместо себя. Вы вызываете метод в экземпляре, а не в своем классе.

Если вы определяете метод с помощью self, вы определяете метод как класс, а не экземпляр. В своем коде вы создаете новый экземпляр класса RubyCsvRow и вам необходимо определить method_missing как метод instace.

Изменить код здесь:

class RubyCsvRow
  attr_accessor :values

  def initialize(start)
    @values = start
  end

  # Define method missing on instance
  def method_missing(name, *args, &block)
    return @values[name.to_s] if @values[name.to_s]
    # return my error message
    "No Column with name: #{name} found!"
  end

  def to_s
    inspect
  end
end

r = RubyCsvRow.new({ "one" => "dog", "two" => "cat" })
puts r.one
# => dog
puts r.test
# => "No Column with name: test found!"

Кстати: если вам нужно исходное сообщение об ошибке, используйте super в method_missing метод

def method_missing(name, *args, &block)
  return @values[name.to_s] if @values[name.to_s]
  # call original method
  super
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...