Как вызвать `self.class` из смешанного модуля? - PullRequest
1 голос
/ 25 июня 2019

У меня есть модуль для включения в другие классы. Он использует метод Object # class , например: ( ссылка на sorbet.run )

# 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?

Теперь это становится интересным. Ссылка на ошибку для 7003 описывает, что это защищает от ошибок типа в модулях, которые будут включены в BasicObject. Хорошо, поэтому я включаю Object, как говорит мне контролер: ( sorbet.run link )

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

Сообщение об ошибке совершенно бесполезно, и связанная страница # 5032 не существует.

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

Мне потребовалось некоторое время, чтобы понять, что он пытается сказать мне, что я не могу включить класс, который является подклассом модуля. Сравните с сообщением об ошибке Руби:

$ 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 ]

3 голосов
/ 25 июня 2019

На самом деле это были две ошибки! Спасибо за указание на них:

class не было в наших прокладках на Kernel: https://github.com/sorbet/sorbet/pull/1050 и мы никогда не должны предлагать включать что-то, что не является Module: https://github.com/sorbet/sorbet/pull/1047

0 голосов
/ 25 июня 2019

Мой текущий обходной путь: ( ссылка sorbet.run )

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