0

我正在研究 Ruby 并尝试实现method_missing,但它不起作用。例如,我想在之后打印方法名称,find_但是当我在 Book 实例上调用它时,ruby 会引发“未定义的方法'find_hello'”。

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
4

2 回答 2

3

您正在调用object查找方法的instance_level方法。所以你需要定义 instance_levelmethod_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

当您使用selfwith 方法定义时。它被定义为class level方法。在您的情况下Book.find_hello将输出hello.

于 2013-03-24T06:25:15.540 回答
2

您已在 上定义method_missing方法Searchable,但您试图将其作为实例方法调用。要按原样调用该方法,请针对该类运行它:

Book.find_hello

如果您的目的是从整个图书收藏中找到一些东西,那么这是完成的规范方式。ActiveRecord 使用这种方法。

类似地,您可以有一个find_*实例方法来搜索当前书籍实例中的某些内容。如果这是您的意图,请更改def self.method_missingdef method_missing.

于 2013-03-24T06:27:50.517 回答