buyoh
@buyoh (mai)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

Ruby + RBS + steep で型変換をしたい

Q&A

Closed

環境

$ ruby --version
ruby 2.7.0p0 (2019-12-25 revision 647ee6f091) [x86_64-linux]
$ rbs --version
rbs 1.0.3
$ steep --version
0.39.0

解決したいこと

Array[String | nil] から Array[String] に変換させる方法が分かりませんでした。

発生している問題・エラー

以下の型注釈と

# RBS
class K
  def pull: () -> Array[String?]
  def echo: (Array[String]) -> nil
  def main: () -> untyped
end

以下のrubyコードを書きました。

# Ruby
class K
  def pull
    3.times.map { gets }
  end

  def echo(strs)
    strs.each { |str| puts str.upcase }
    nil
  end

  def main
    echo pull.compact
  end
end

K.new.main

pullnil を含む配列が作られますが、compact している為、これはエラー無く動作します。
結果は以下の通り(行番号が異なっています)、compact したにも関わらず、型情報にnilが残るため、失敗しています。

$ steep check
lib/test.rb:14:9: ArgumentTypeMismatch: receiver=::K, expected=::Array[::String], actual=::Array[(::String | nil)] (pull.compact)

nilが含まれていないことを steep に伝えるにはどのように記述すべきでしょうか。可能であれば、実行時の性能劣化も抑えたいです。

0

1Answer

軽く調べた限りではアノテーションだけで解決する方法は見つかりませんでした。 pull.compact の結果を untyped なローカル変数に入れれば型検査をパスできます。

  def main
    # @type var strs: untyped
    strs = pull.compact
    echo strs
  end

1Like

Comments

  1. @buyoh

    Questioner

    ありがとうございます。
    一旦untypedに代入するんですね…今のバージョンはこの方法で進めようと思います。

Your answer might help someone💌