如何从混入模块调用`self.class`?

时间:2019-06-25 16:57:28

标签: ruby sorbet

我有一个要包含在其他课程中的模块。它使用Object#class方法,如下所示: (sorbet.run link

# typed: true
module M
  def foo
    self.class
  end
end

对此,索贝特说

editor.rb:4: Method class does not exist on M https://srb.help/7003
     4 |    self.class
            ^^^^^^^^^^
  Did you mean to `include Object` in this module?
    ???: Did you mean: Object#class?

现在变得有趣了。 Error reference for 7003确实描述了此方法可防止BasicObject中要包含的模块中的类型错误。很好,所以我包括了对象,就像检查器告诉我的那样:(sorbet.run link

# typed: true
module M
  include Object
  def foo
    self.class
  end
end

该错误消息非常无用,并且链接的page #5032不存在。

editor.rb:2: Only modules can be included. This module or class includes Object https://srb.help/5032
     2 |module M
        ^^^^^^^^

我花了一段时间才意识到,它试图告诉我我不能包含作为Module子类的Class。与Ruby的错误消息进行比较:

$ ruby -e 'module M; include Object; end'
Traceback (most recent call last):
        2: from -e:1:in `<main>'
        1: from -e:1:in `<module:M>'
-e:1:in `include': wrong argument type Class (expected Module) (TypeError)

如何使我的代码通过typed: true级?

2 个答案:

答案 0 :(得分:3)

这实际上是两个错误!感谢您指出它们:

class不是我们对Kernel的看法:https://github.com/sorbet/sorbet/pull/1050 并且我们绝不建议包含非Modulehttps://github.com/sorbet/sorbet/pull/1047

答案 1 :(得分:0)

我当前的解决方法是:(sorbet.run link

# typed: true
module ObjectInterface
  def class; super; end
end
module M
  include ObjectInterface
  def foo
    self.class
  end
end