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

Yla's #Kaigieffect

Yla's #Kaigieffect

https://cookpad.connpass.com/event/282436/
手を動かして振り返る RubyKaigi 2023でLTしました.

Yla Aioi

May 18, 2023
Tweet

More Decks by Yla Aioi

Other Decks in Programming

Transcript

  1. 相生ゆらの #Kaigieffect
    Yla Aioi (@Little_Rubyist)

    View Slide

  2. 今回話す人
    相生ゆら/Yla Aioi
    @Little_Rubyist @Little-Rubyist
    RBSとRuboCopに興味があります
    2023/02~

    View Slide

  3. - lramaにPR出した
    - 会社のプロジェクトにRBS導入を始めた
    - RBS導入時のポイント
    アジェンダ

    View Slide

  4. 今回のRubyKaigiは
    大パーサー時代でしたね
    lramaの話

    View Slide

  5. lramaの話

    View Slide

  6. lramaの話

    View Slide

  7. というわけで

    View Slide

  8. lramaの話

    View Slide

  9. やったこと
    lramaの話

    View Slide

  10. rbs, steepを入れる
    lramaの話

    View Slide

  11. 挙動確認のために
    適当なファイルに型をつける
    lramaの話

    View Slide

  12. Github Actionに
    Steep checkを追加する
    lramaの話

    View Slide

  13. PRを出して終わり :tada:
    lramaの話

    View Slide

  14. ちなみに初contributeでした
    lramaの話

    View Slide

  15. あなたがlramaに
    RBSを追加したいときに
    やるべきこと
    lramaの話

    View Slide

  16. 型付けするファイルを決める
    lramaの話

    View Slide

  17. (現状は)
    steepfileに狙いをつけたファイルを
    checkさせる
    lramaの話

    View Slide

  18. ファイルの中身を読む
    lramaの話

    View Slide

  19. RBSを書く
    lramaの話

    View Slide

  20. ruby/lramaに
    PR出して祈る :pray:
    lramaの話

    View Slide

  21. lramaは金子さんがRBS
    入れようとしてくれていますが
    他gemはあんまりっぽい
    gem_rbs_collection

    View Slide

  22. そういう時はgem_rbs_collectionに
    新しいgemを追加したり
    既存gemの型を足していきましょう
    gem_rbs_collection

    View Slide

  23. え,gemは使ってるけど
    プロジェクトでは
    一部のmethodしか使ってない?
    gem_rbs_collection

    View Slide

  24. そんな状況で1ファイルの
    型付けは厳しい?
    gem_rbs_collection

    View Slide

  25. わかる〜〜〜!!!!!
    gem_rbs_collection

    View Slide

  26. 1method 1PR
    でも大丈夫です :+1:
    gem_rbs_collection

    View Slide

  27. もし不安な時は手元で
    patch的に型を付けてから
    PRを出しましょう
    gem_rbs_collection

    View Slide

  28. 私の例を話しましょう
    会社のプロジェクトにRBS入れた話

    View Slide

  29. 手順

    View Slide

  30. steep, rbs_rails
    を入れる

    View Slide

  31. rbs_rails:generate_rbs_for_models
    を走らせる

    View Slide

  32. 動かないので困る

    View Slide

  33. composite-primary-key
    を使っていた

    View Slide

  34. rbs_railsのprimary_key部を
    変える

    View Slide

  35. class Generator < RbsRails::ActiveRecord::Generator
    private
    def pk_type
    pk = klass.primary_key
    return 'top' unless pk
    if pk.instance_of?(::CompositePrimaryKeys::CompositeKeys)
    sql_types = []
    pk.each do |x|
    col = klass.columns.find { |column| column.name == x }
    sql_types << sql_type_to_class(col.type)
    end
    return sql_types.join(' | ')
    end
    col = klass.columns.find { |column| column.name == pk }
    sql_type_to_class(col.type)
    end
    end

    View Slide

  36. 通った :tada:

    View Slide

  37. > bundle exec steep check
    > Detected 714 problems from 91
    files

    View Slide

  38. Rails wayに沿ってないので
    余計にエラーが出る

    View Slide

  39. これが3/2

    View Slide

  40. 大体は定義したら解決したけど
    どれだけ悩んでも分からない子も
    結構いた

    View Slide

  41. included do…endの中で
    定義しているので
    include先のclassが持ってる
    methodが分からない

    View Slide

  42. module SomeModule
    extend ActiveSupport::Concern
    included do
    # @type self: ClassMethods & singleton(ApplicationRecord)
    ...
    end
    型注釈してあげる

    View Slide

  43. 明らかにお前はModuleだろ…
    と思うのに
    define_methodを知らないと言う

    View Slide

  44. module Models::UndefinedDateTimeAttribute
    extend ActiveSupport::Concern
    module ClassMethods : Module
    def attr_undefined_datetime: (untyped column) -> void
    end
    end
    実はこれどういう時に使うか
    分かってない.
    moduleそのものの情報を足してあげる

    View Slide

  45. read_attributeやscopeに
    blockが必須と言われる

    View Slide

  46. 必須ではないので
    blockを持たない型を足してあげる

    View Slide

  47. module ActiveRecord
    module AttributeMethods
    module Read
    extend ActiveSupport::Concern
    def read_attribute: (untyped attr_name) -> untyped
    | ...
    end
    end
    module Scoping
    module Named
    extend ActiveSupport::Concern
    module ClassMethods
    def scope: (untyped name, untyped body) -> untyped
    | ...
    end
    end
    end
    end

    View Slide

  48. みたいなのを延々とやりました

    View Slide

  49. この辺は全部RubyKaigi中に
    @pockeと@soutaroに
    助けてもらいました
    thanks!

    View Slide

  50. 一昨日

    View Slide

  51. それなりに出来たので
    katakata_irb導入
    thanks @tompng

    View Slide

  52. しかしちょっと問題があって

    View Slide

  53. 今回簡単なところから
    RBSを入れたので
    models/しか対応していない

    View Slide

  54. ので
    あんまりkatakata_irbでは
    自前RBSの恩恵を
    受けられていなさそう

    View Slide

  55. まあnilableとかのエラーは
    見つけたのでいいか!

    View Slide

  56. 型書くの楽しいです

    View Slide

  57. 便利command

    View Slide

  58. bundle exec rbs -I sig
    method Hoge foo?

    View Slide

  59. bundle exec rbs -I sig
    method Hoge foo?
    RBSファイルの定義場所

    View Slide

  60. bundle exec rbs -I sig
    method Hoge foo?
    RBSファイルの定義場所
    method コマンド 最強

    View Slide

  61. bundle exec rbs -I sig
    method Hoge foo?
    RBSファイルの定義場所
    method コマンド 最強
    探したいmethod

    View Slide

  62. ❯ bundle exec rbs -I sig method --singleton Hoge find
    ::hoge.find
    defined_in: ::_ActiveRecord_Relation_ClassMethods
    implementation: ::OfficialComicGroup
    accessibility: public
    types:
    (::Integer id) -> ::Hoge
    | (::Array[::Integer]) -> ::Array[::Hoge]
    | (*::Integer) -> ::Array[::Hoge]
    便利だね〜〜〜

    View Slide

  63. これで見つからなかったら
    型注釈を足すとか
    型定義を足すとか
    includeとかしてあげるとか

    View Slide

  64. 何かどう足掻いても直せない時
    -> ruby-jp #types
    に投げるとよいです

    View Slide

  65. あまったら喋るやつ

    View Slide

  66. 今まだ直せてない謎エラー達

    View Slide

  67. View Slide

  68. ガード文書いてるのに
    association系でchild.age?
    的なmethodやると
    nilableなエラーが出る
    (一般的なコードにする時間なかった)

    View Slide

  69. 解決法がわかる人がいたら
    教えて下さい〜

    View Slide