Неопределенный метод даже после обработки method_missing

Я изучаю Ruby и пытаюсь реализовать method_missing, но это не работает. Например, я хочу напечатать имя метода после find_ но ruby ​​вызывает "неопределенный метод 'find_hello'", когда я вызываю его в экземпляре Book.

TEST_05.RB

module Searchable
    def self.method_missing(m, *args)
        method = m.to_s
        if method.start_with?("find_")
            attr = method[5..-1]
            puts attr
        else
            super
        end
    end
end

class Book

    include Searchable

    BOOKS = []
    attr_accessor :author, :title, :year

    def initialize(name = "Undefined", author = "Undefined", year = 1970)
        @name = name
        @author = author
        @year = year
    end
end


book = Book.new
book.find_hello

2 ответа

Решение

Вы вызываете метод на object который ищет instance_level метод. Так что вам нужно определить instance_level method_missing метод:

module Searchable
    def method_missing(m, *args)
        method = m.to_s
        if method.start_with?("find_")
            attr = method[5..-1]
            puts attr
        else
            super
        end
    end
end

class Book

    include Searchable

    BOOKS = []
    attr_accessor :author, :title, :year

    def initialize(name = "Undefined", author = "Undefined", year = 1970)
        @name = name
        @author = author
        @year = year
    end
end


book = Book.new
book.find_hello   #=> hello

Когда вы используете self с определением метода. Определяется как class level метод. В твоем случае Book.find_hello будет выводить hello,

Вы определили method_missing как метод класса на Searchable, но вы пытаетесь вызвать его как метод экземпляра. Чтобы вызвать метод как есть, запустите его для класса:

Book.find_hello

Если вы хотите найти что-то из всей коллекции книг, это канонический способ. ActiveRecord использует этот подход.

Вы могли бы так же иметь find_* Метод экземпляра, который будет искать текущий экземпляр книги для чего-то. Если это ваше намерение, то измените def self.method_missing в def method_missing,

Другие вопросы по тегам