消除 Ruby 中的函数调用歧义

Disambiguate Function calls in Ruby

我正在学习 Ruby The Hard Way,并在 exercise 49 中发现了一些有趣的东西。

parser.rb中我在顶层有一个名为skip(word_list, word_type)的函数,用于跳过用户输入中不需要的词(例如停用词)。它没有封装在 class 或模块中。根据练习,我必须为解析器编写单元测试。

这是我的单元测试代码:

require "./lib/ex48/parser"
require "minitest/autorun"

class TestGame < Minitest::Test

  def test_skip()
    word_list = [['stop', 'from'], ['stop', 'the'], ['noun', 'west']]

    assert_equal(skip(word_list, 'stop'), nil)
    assert_equal(skip([['noun', 'bear'], ['verb', 'eat'], ['noun', 'honey']], 'noun'), nil)
  end
end

但是,当我从命令行运行 rake test TESTOPTS="-v" 时,这些特定的测试被跳过了。这似乎是因为与 Minitest 模块中的 skip 方法发生冲突,因为我将名称更改为 skip_words.

后它们运行完美

有人可以解释一下这里到底发生了什么吗?

"Top level functions" 实际上也是方法,特别是它们是 Object 上的私有实例方法(main 对象有些有趣,但这在这里并不重要)

但是 minitest 的测试 class 也有一个 skip 方法,并且由于各个测试是 Test 的子 class 上的实例方法,所以您最终会调用该 skip相反。

没有一种非常简单的方法来处理这个问题 - 与某些语言不同,没有简单的方法来表示您想要调用某个特定的超级class'实现

除了重命名您的方法,您还必须选择另一种调用方法,例如:

Object.new.send(:skip, list, type)
Object.instance_method(:skip).bind(self).call(list, type)

当然,您可以将它包装在测试的辅助方法中,甚至可以为这个特定的 Test subclass 重新定义 skip(尽管这可能会导致有人在尝试调用 minitest 的 skip