Ruby类型和单例方法

9rygscc1  于 2023-04-29  发布在  Ruby
关注(0)|答案(1)|浏览(87)

我看到在现有的Ruby项目上设置RBS类型时出现了一些意想不到的行为。一个最小的例子:

# lib/a.rb
class A
  def self.foo
    new
  end
end

class B < A
  def self.foo
    super
  end
end

puts A.foo.inspect
puts B.foo.inspect

输出

#<A:0x000055f7cfb03908>
#<B:0x000055f7cfb037f0>

签名

# lib/a.rbs
class A
  def self.foo: () -> A
end

class B < A
  def self.foo: () -> B
end

但是陡峭的类型检查器给我错误

lib/a.rb:8:11: [error] Cannot allow method body have type `::A` because declared as type `::B`
│   ::A <: ::B
│     ::Object <: ::B
│       ::BasicObject <: ::B
│
│ Diagnostic ID: Ruby::MethodBodyTypeMismatch
│
└   def self.foo
             ~~~

这是一个陡峭的问题,还是(更有可能)我对Ruby类型语法的理解有问题?

wxclj1h5

wxclj1h51#

这是一个陡峭的问题,还是(更有可能)我对Ruby类型语法的理解有问题?
我认为两者都不是。
你的语法非常好(否则steep甚至不能解析RBS文件,并给予你一个语法错误),我也没有看到任何问题。根据你声明的类型,你的代码是 * 真正 * 类型不安全的:

  • B::foo声明为返回B的示例
  • B::foo返回super
  • superA::foo
  • A::foo声明为返回A的示例
    *因此B::foo声明为返回B的示例,但实际上返回A的示例。

由于A不能转换为B,因此这不是类型安全的。

相关问题