Upgrade to Pro — share decks privately, control downloads, hide ads and more …

拙者、『型は欲しいが型は書きたくない』者たちとの和睦を結び、るびぃにおける型の領地安堵を実現せ...

230

拙者、『型は欲しいが型は書きたくない』者たちとの和睦を結び、るびぃにおける型の領地安堵を実現せんと欲す者也 #sekigahara01/sekigahara01

Avatar for Masatoshi Moritsuka

Masatoshi Moritsuka

May 31, 2026

More Decks by Masatoshi Moritsuka

Transcript

  1. 例: 型に気持ちのある人 vs 型に気持ちのない人 型に気持ちのある人 型大好き!Ruby でも型安全! 最終的には型は書きたくない だから型にコントリビュートしている 型に気持ちのない人

    型の話題に全く興味がない Ruby に型なんて不要 「型が不要」という気持ちがあるという見方もできる 「気持ちがある/ない」をポジティブ/ネガティブで分類するのは適切なのか? 「気持ちがある/ない」ことを「型に対して肯定/否定的」というように捉えてしまっていないか?
  2. 型は書きたくない 理由 型のためのコードを書きたくな い 型を書くメリットを感じない 型を書くのが面倒 型の文法を覚えたくない 型を保守したくない 範囲 ライブラリ含めて全部

    アプリケーションコード全体 主要でない部分(private 等) 手段 自動生成でも型を書きたくない 手動では型を書きたくない
  3. 型は書きたくない理由 主要因が型検査によるものがほとんどではないか? 理由 型のためのコードを書きたくな い 型を書くメリットを感じない 型を書くのが面倒 型の文法を覚えたくない 型を保守したくない 範囲

    ライブラリ含めて全部 アプリケーションコード全体 主要でない部分(private 等) 手段 自動生成でも型を書きたくない 手動では型を書きたくない
  4. 偽陽性に対するヘイト 本質的ではない コードが Ruby っぽくなくなる テストでカバーできるケースが多い def bushou_hash(users) user =

    users.find(&:bushou?) || raise # <= こういうやつとか { id: user.id, name: user.name } end def daimyou_hash(users) user = users.find(&:daimyou?) { id: (user || raise).id, name: (user || raise).name } # <= こういうやつとか end def ashigaru_hash(users) user = users.find(&:ashigaru?) { id: user.id, name: user.name } # steep:ignore -- こういうやつとか end
  5. RubyKaigi 2019 Keynote by Matz 型を書くことに対する言及 これも型を書くことが型検査をするために書くものという前提になっていそう 型宣言嫌いなんですよね。なんでかっていうと DRY じゃないからなん

    ですよ。今私達の書いている Ruby のプログラムは型宣言ないんです ね。で、それでもちゃんと動いているんですよ。それに対してさらに情 報を付け加えるっていうのはなんかこうコンピュータに仕事をさせられ ている感じがするわけですよね。本当はコンピュータが私達のために働 いてほしい。 https://youtu.be/WZu-WVzbEOA?si=b3kkPGV630GeUzGn&t=334
  6. RubyKaigi 2019 Keynote by Matz 型検査のために型を書くからコンピュータに仕事をさせられている感じがする ドキュメントは人のためという側面が強い ドキュメントのための型ならコンピュータに仕事をさせられている感じはなくなるのでは? 型宣言嫌いなんですよね。なんでかっていうと DRY

    じゃないからなん ですよ。今私達の書いている Ruby のプログラムは型宣言ないんです ね。で、それでもちゃんと動いているんですよ。それに対してさらに情 報を付け加えるっていうのはなんかこうコンピュータに仕事をさせられ ている感じがするわけですよね。本当はコンピュータが私達のために働 いてほしい。 https://youtu.be/WZu-WVzbEOA?si=b3kkPGV630GeUzGn&t=334
  7. 型シグネチャはドキュメントの表現として非常に有用 yard のタグよりも rbs の方が表現力が高い # こっちより # # @param

    bar [Hash{Symbol=>String,Integer}] key は uuid・name・age で age は optional、uuid は UUIDv4 形式 # @return [Foo] 〇〇 な ☓☓ def foo(bar) # こっちの方が表現力が高い # # @rbs bar: { uuid: String, name: String, ?age: Integer } -- uuid は UUIDv4 形式 # @rbs return: Foo -- 〇〇 な ☓☓ def foo: ({ id: Integer, name: String, ?age: Integer } bar) -> Foo
  8. 型シグネチャは仕様のサマリなので概観を把握しやすい module Ancestry module HasAncestry def has_ancestry: (?{ ?ancestry_column: String

    | Symbol, ?orphan_strategy: :destroy | :rootify | :restrict | :adopt | :none, ?cache_depth: bool | String | :virtual | Symbol, ?depth_cache_column: String | Symbol, ?touch: bool, ?counter_cache: bool | String | Symbol, ?primary_key_format: '[0-9]+' | '[-A-Fa-f0-9]{36}', ?update_strategy: :sql | :ruby, ?ancestry_format: :materialized_path | :materialized_path2 } options) -> void gem_rbs_collection/gems/ancestry/5.1/ancestry/has_ancestry.rbs
  9. DSL への対応が進まない RBI(Tapioca) には がある RBS は都度独自実装と の 2 派閥ある(

    ) が仕組み的によくできていて自分はすごく推している 規約があるので AI とも相性がいい が、利用者を殆ど見かけない ドキュメントや利用事例が足りない DSL Compiler orthoses 参考 orthoses
  10. 導入してからも必要な手数が多い rbs collection install / update テスト(rbs-trace のため) rbs-inline orthoses-rails

    or rbs_rails 定期アップデート(dependabot/renovate) dependabot も revovate も対応していない 自前で定期更新用の仕組みを組まないといけない
  11. 2. bundler と rbs collection の統合 bundle install / update

    を実行すると rbs collection install / update も走る から着想 bundler の plugin によるフック機構を利用 typesync