ほとんど一緒なので気にすることはあまりないとは思います。
タイトル通り、RBSとRubyでは定数探索がちょっとだけ違います。
具体的にはスーパークラスやinclude
元のモジュールで定義された定数がRBSでは参照できません。
Rubyの場合
まずはRubyの場合の挙動を確認しましょう。 次のRubyのコードを題材にします。
# Ruby module M class A end end class P class B end end module N class C < P include M def foo A.new end def bar B.new end end end obj = N::C.new p obj.foo # => #<M::A:0x0000564e4c1cb178> p obj.bar # => #<P::B:0x0000564e4c1cafc0>
このコードの実行結果からわかるとおり、Rubyではスーパークラスやinclude
元のモジュールで定義された定数を、その子クラスから参照できます。
つまり、N::C
の中でA
を参照すると、それはN::C
がinclude
しているモジュールM
で定義されたM::A
を指します。
またN::C
の中でB
を参照すると、N::C
のスーパークラスのP
の中で定義されたP::B
を指します。
RBSの場合
ところがRBSの場合にはこの挙動が違います。
RBSではスーパークラスやinclude
元で定義された定数を参照できません。
# RBS module M class A end end class P class B end end module N class C < P include M # def foo: () -> A だとAを参照できないため、 # M::Aのようにフルネームを書く必要がある def foo: () -> M::A # def bar: () -> B だとBを参照できない # P::Bのようにフルネームを書く必要がある def bar: () -> P::B end end
Rubyのコードを見ながら型定義を書いている場合や、rbs prototype rb
を使って型定義を生成している場合、この問題にハマることがあるかもしれません。
その時は正しい型が参照できるよう、型名の参照をより詳しい名前で書くと良いでしょう。
ちなみにこの挙動以外はだいたいRubyとRBSで定数探索は同じような挙動をすると思います。
参考
Type name resolution became more compatible with Ruby's constant resolution. It resolves given relative type names based on class/module nesting structure. Note that the type name resolution does not refer inheritance and includes.