作为编程练习,我编写了一个Ruby代码段,创建一个类,实例化该类中的两个对象,monkeypatches一个对象,并依赖monkeypatch另一个缺少的方法_.

事情是这样的.这样做的目的是:

class Monkey

  def chatter
    puts "I am a chattering monkey!"
  end

  def method_missing(m)
    puts "No #{m}, so I'll make one..."
    def screech
      puts "This is the new screech."
    end
  end
end

m1 = Monkey.new
m2 = Monkey.new

m1.chatter
m2.chatter

def m1.screech
  puts "Aaaaaargh!"
end

m1.screech
m2.screech
m2.screech
m1.screech
m2.screech

您会注意到,我有一个参数表示方法_缺失.我这样做是因为我希望使用define_方法来动态创建具有适当名称的缺少的方法.然而,它不起作用.事实上,即使使用带有静态名称的define_方法,如下所示:

def method_missing(m)
  puts "No #{m}, so I'll make one..."
  define_method(:screech) do
    puts "This is the new screech."
  end
end

以以下结果结束:

ArgumentError: wrong number of arguments (2 for 1)

method method_missing   in untitled document at line 9
method method_missing   in untitled document at line 9
at top level    in untitled document at line 26
Program exited.

让错误信息更令人困惑的是,我只有一个method_missing的论点...

推荐答案

define_method是对象Class的(私有)方法.你是从instance号角打过来的.没有名为define_method的实例方法,因此它会递归到method_missing,这次是:define_method(缺少的方法的名称)和:screech(传递给define_method的唯一参数).

请try 以下方法(在所有Monkey对象上定义新方法):

def method_missing(m)
    puts "No #{m}, so I'll make one..."
    self.class.send(:define_method, :screech) do
      puts "This is the new screech."
    end
end

或者这样(只在调用它的对象上定义它,使用对象的"本征类"):

def method_missing(m)
    puts "No #{m}, so I'll make one..."
    class << self
      define_method(:screech) do
        puts "This is the new screech."
      end
    end
end

Ruby相关问答推荐

指南针手表:未定义的方法存在吗?对于文件:类

如何使用 HEREDOC 作为参数传递给方法?

生成带有小写字母和数字的唯一随机字符串

如何在 ruby​​ 中通过 SSL 调用 HTTP POST 方法?

将 ruby​​ hash .default 设置为列表

Rails 类 << self

使用 Ruby MiniTest 之前/之后的套件

如何在不按 Enter 的情况下获取单个字符?

确定字符串数组是否包含ruby中的某个子字符串

如何声明 RSpec 中示例之间共享的变量?

在现有 Jekyll 安装中切换主题

如何在Ruby中对数组中对象的属性求和

错误:Windows 的 SASS 安装

Sublime Text 2 控制台输入

在 Ruby 中查找内存泄漏的原因

将两个数组组合成哈希

判断散列的键是否包含所有键集

在ruby中将字符串转换为十进制数

如果公司使用 C++、C# 或 Java 作为应用程序语言,为什么要学习 Perl、Python、Ruby?

JavaScript Array:获取项目的范围