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

RuboCop Under a Microscope

Koichi ITO
November 18, 2022

RuboCop Under a Microscope

Koichi ITO

November 18, 2022
Tweet

More Decks by Koichi ITO

Other Decks in Programming

Transcript

  1. ҏ౻ߒҰ&4. *OD
    Lint Night #1
    3VCP$PQͷ͘͠Έ
    RuboCop Under a
    Microscope
    % ruby -v
    ruby 3.2.0dev
    % rubocop -v
    1.39.0

    View Slide

  2. @koic
    w044ϓϩάϥϚʔ
    w3VCP$PQίΞνʔϜ
    wגࣜձࣾӬ࿨γεςϜϚωδϝϯτ &4. *OD

    ΤϯδχΞϦϯάϚωʔδϟʔ݉
    σΟεςΟϯάΠογϡυΤϯδχΞ

    View Slide

  3. View Slide

  4. 044ίϛϡχςΟͱͷڞੜΛࢧԉ
    3BJMT044ύονձ
    #esm_oss

    View Slide

  5. 3VCP$PQDPSFEFWFMPQFST
    +0900
    UTC+0200 +0300 +0800 -0400
    .PSFUIBODPOUSJCVUPST

    View Slide

  6. 3VCP$PQDPSFEFWFMPQFST
    +0900
    UTC+0200 +0300 +0800 -0400
    .PSFUIBODPOUSJCVUPST
    "VUIPS

    View Slide

  7. 5IFpSTUDPNNJU
    % git log -p --reverse
    commit afbead34db54506c12a21dbd4ce04fada0f8b9a4
    Author: Bozhidar Batsov
    Date: Sat Apr 21 13:06:42 2012 +0300
    Initial commit to rubocop.
    ---
    .document | 5 +++++
    .gitignore | 49 +++++++++++++++++++++++++++++++++++++++
    ++++++++++
    .rspec | 1 +
    Gemfile | 16 ++++++++++++++++
    LICENSE.txt | 20 ++++++++++++++++++++
    README.rdoc | 19 +++++++++++++++++++
    Rakefile | 45 +++++++++++++++++++++++++++++++++++++++
    ++++++
    features/rubocop.feature | 9 +++++++++
    features/step_definitions/rubocop_steps.rb | 0
    features/support/env.rb | 13 +++++++++++++

    View Slide

  8. 5IFpSTUDPNNJU
    % git log -p --reverse
    commit afbead34db54506c12a21dbd4ce04fada0f8b9a4
    Author: Bozhidar Batsov
    Date: Sat Apr 21 13:06:42 2012 +0300
    Initial commit to rubocop.
    ---
    .document | 5 +++++
    .gitignore | 49 +++++++++++++++++++++++++++++++++++++++
    ++++++++++
    .rspec | 1 +
    Gemfile | 16 ++++++++++++++++
    LICENSE.txt | 20 ++++++++++++++++++++
    README.rdoc | 19 +++++++++++++++++++
    Rakefile | 45 +++++++++++++++++++++++++++++++++++++++
    ++++++
    features/rubocop.feature | 9 +++++++++
    features/step_definitions/rubocop_steps.rb | 0
    features/support/env.rb | 13 +++++++++++++
    👈

    View Slide

  9. UI"OOJWFSTBSZZFBS🎉

    View Slide

  10. 3VCP$PQDPSFEFWFMPQFST
    +0900
    UTC+0200 +0300 +0800 -0400
    .PSFUIBODPOUSJCVUPSTJOZFBST
    .F

    View Slide

  11. View Slide

  12. .BJOUBJO3VCP$PQ)2&WFSZ%BZ
    IUUQTHJUIVCDPNLPJD PSHSVCPDPQ

    View Slide

  13. .F

    View Slide

  14. ໨࣍
    ߏจղੳͷ͘͠Έ
    ੩తղੳͷ͘͠Έલฤ
    ੩తղੳͷ͘͠Έޙฤ

    View Slide

  15. ੩తղੳͷུ֓
    ࣈ۟ղੳ ߏจղੳ ੩తղੳ
    Ϩϙʔτ
    ιʔείʔυ
    ೖྗ
    ॲཧ
    ग़ྗ

    View Slide


  16. ߏจղੳͷ͘͠Έ

    View Slide

  17. ࣈ۟ղੳͱߏจղੳ
    ࣈ۟ղੳ ߏจղੳ ੩తղੳ
    Ϩϙʔτ
    ιʔείʔυ
    ೖྗ
    ॲཧ
    ग़ྗ

    View Slide

  18. w 3VCZͷίʔυΛύʔε͢Δ3VCZ੡ύʔαʔ
    w 3VCZຊମͷύʔαʔͱ͸ҟͳΔ
    w 3VCP$PQҎ֎Ͱ͸0QBM 3VCZ/FYUͳͲͰར
    ༻͞Ε͍ͯΔ
    w 3VCP$PQ͸1BSTFSHFNʹΑΔߏจղੳʹ
    ґଘ͢Δ
    1BSTFSHFN

    View Slide

  19. w 3VCZຊମ͕ߏจఆ͍ٛͯ͠ΔQBSTFZͷมߋ
    Λ௥͍ͬͯΔ ͍ΘΏΔSEύʔςΟ੡඼

    w 3VCZຊମͰ৽͍͠ߏจ௥Ճ͕͋ͬͯ΋
    1BSTFSHFNଆͷߏจఆٛʹಉ༷ͷύονΛ
    खΛೖΕͳ͍ͱɺ৽͍͠ߏจΛղੳͰ͖ͳ͍
    w ݱࡏ0QBMίϛολʔ͕Ϧʔυ͍ͯ͠Δ
    3VCZߏจղੳͷ࣮૷ͷͻͱͭ

    View Slide

  20. ߏจղੳͱͦͷઌ
    ੩తղੳ
    3VCP$PQ
    1PMZpMM
    3VCZ/FYU
    τϥϯεύΠϥ
    0QBM
    ߏจղੳ
    1BSTFS
    3VCZίʔυ "45
    ݹ͍ϥϯλΠϜ
    3VCZίʔυ
    +BWB4DSJQUίʔυ
    ੩తղੳޙͷमਖ਼
    3VCZίʔυ
    1SPDFTTFE4PVSDF

    View Slide

  21. w 1BSTFSHFN͸όʔδϣϯ͝ͱͷ3VCZߏจΛ
    #/' όοΧεɾφ΢Ξه๏
    Ͱఆٛͯ͠Δ
    3VCP$PQ1BSTFS͕ॲཧ͢Δߏจ
    ͷͪͷ෬ઢʹͳΓ·͢💡

    View Slide

  22. w ίϩϯ
    ͷࠨลͷ୯
    Ұͷه߸͕ӈลʹߏ੒
    ͞Ε͍ͯΔه߸ͷฒͼ
    Ͱஔ׵͞ΕΔ
    w 1BSTFSHFNͰ͸3BDD
    ͱ͍͏ύʔαδΣω
    ϨʔλΛ࢖͍ͬͯΔ
    Zͷ#/'αϯϓϧ

    View Slide

  23. % cd ghq/github.com/whitequark/parser
    % bundle exec rake generate # Generate the Ragel lexer and Racc parser
    (snip)
    % ls lib/parser/
    all.rb macruby.rb ruby22.y ruby32.rb
    ast macruby.y ruby23.rb ruby32.y
    base.rb max_numparam_stack.rb ruby23.y rubymotion.rb
    builders messages.rb ruby24.rb rubymotion.y
    clobbering_error.rb meta.rb ruby24.y runner
    color.rb rewriter.rb ruby25.rb runner.rb
    context.rb ruby18.rb ruby25.y source
    current.rb ruby18.y ruby26.rb static_environment.rb
    current_arg_stack.rb ruby19.rb ruby26.y syntax_error.rb
    deprecation.rb ruby19.y ruby27.rb tree_rewriter.rb
    diagnostic ruby20.rb ruby27.y variables_stack.rb
    diagnostic.rb ruby20.y ruby30.rb version.rb
    lexer ruby21.rb ruby30.y
    lexer.rb ruby21.y ruby31.rb
    lexer.rl ruby22.rb ruby31.y
    Z͔ΒSC͕ੜ੒͞ΕΔ

    View Slide

  24. 3VCZ͔Β1BSTFS΁ͷҠ২ྫ

    View Slide

  25. XIJUFRVBSLQBSTFS
    SVCZZ"MMPXUSBJMJOHDPNNBJOIBTIQBUUFSO

    View Slide

  26. DEdTSDHJUIVCDPNSVCZSVCZ
    HJUMPHQQBSTFZ
    DPNNJUEBGEDFBEBCBBGCBDDF
    "VUIPS,B[VLJ5TVKJNPUPLB[VLJ!DBMMDDOFU
    %BUF4VO.BS
    "MMPXUSBJMJOHDPNNBJOIBTIQBUUFSO
    EJ⒎HJUBQBSTFZCQBSTFZ
    JOEFYDDGCG
    BQBSTFZ
    CQBSTFZ
    !! [email protected]@LXBSH [email protected]
    \
    [email protected]@[email protected] Q [email protected]@[email protected] Q !
    !

    ^
    3VCZͷQBSTFZ

    View Slide

  27. IUUQTHJUIVCDPNSVCZSVCZDPNNJUEBG

    View Slide

  28. Trailing comma
    3VCZͷߏจมߋ
    ΧϯϚ͕͋ͬͯ΋ͳͯ͘΋ྑ͘ͳΔ

    View Slide

  29. key: value
    key: value,
    3VCZͷQBSTFZ :BDD

    View Slide

  30. 3VCZ͔Β1BSTFSʹҠ২

    View Slide

  31. 3VCZDPEF
    Trailing comma
    1BSTFSʹςετΛ଍͢

    View Slide

  32. 6TJOH3BDD
    key: value
    key: value,
    1BSTFSͷ#/'Λߋ৽͢Δ

    View Slide

  33. SVCZQBSTFW
    SVCZQBSTFCBTFEPOQBSTFSWFSTJPO
    SVCZQBSTFFDBTFQBUUFSOJO\B ^UIFOUSVF
    FOE
    DBTFNBUDI
    TFOEOJMQBUUFSO

    JOQBUUFSO
    IBTIQBUUFSO
    QBJS
    TZNB

    JOU


    OJM
    USVF

    OJM

    SVCZQBSTFW
    SVCZQBSTFCBTFEPOQBSTFSWFSTJPO
    SVCZQBSTFFDBTFQBUUFSOJO\B^UIFOUSVF
    FOE
    DBTFNBUDI
    TFOEOJMQBUUFSO

    JOQBUUFSO
    IBTIQBUUFSO
    QBJS
    TZNB

    JOU


    OJM
    USVF

    OJM

    ߏจΤϥʔʹͳΒͣॲཧͰ͖Δ
    ΧϯϚ͕͋ͬͯ΋ͳͯ͘΋"45͸ಉ͡

    View Slide

  34. w ৽͍͠3VCZ͕ग़ͯ΋1BSTFSHFN͕ରԠͯ͠
    ͍ͳ͚Ε͹ɺ3VCP$PQ͸৽͍͠ߏจΛղੳ
    Ͱ͖ͳ͍
    w 1BSTFSHFN͸3VCZ͕ϦϦʔε͞ΕΔࠒʹ͸
    ֓Ͷͷߏจ͕αϙʔτͰ͖͍ͯΔ
    w 3VCZͷແ໊Մม௕Ҿ਺ͳͲ΋ରԠࡁΈ
    1BSTFSHFN

    View Slide

  35. w 1BSTFSHFN͸ύʔαδΣωϨʔλ
    ʹ3BDDΛ࢖͍ͬͯΔ
    w #/' όοΧεɾφ΢Ξه๏
    Ͱ
    ॻ͔Ε͍ͯΔ
    w 3BDDΛ࢖ͬͨߏจղੳ͍ͭͯ͸
    ʰຊແಓฤʱͳͲࢀরͷ͜ͱ
    ߏจղੳೖ໳

    View Slide


  36. ੩తղੳͷ͘͠Έલฤ

    View Slide

  37. ੩తղੳ
    ࣈ۟ղੳ ߏจղੳ ੩తղੳ
    Ϩϙʔτ
    ιʔείʔυ
    ೖྗ
    ॲཧ
    ग़ྗ

    View Slide

  38. ֦ுϧʔϧ(FN
    ϥϯλΠϜͱίΞϧʔϧ
    5SBWFSTBM΍ϊʔυ֦ு
    3VCZͷߏจղੳ 1BSTFSHFN
    3VCP$PQ"45
    3VCP$PQDPSF
    3VCP$PQ
    34QFD
    3VCP$PQ
    1FSGPSNBODF
    3VCP$PQ
    3BJMT
    3VCP$PQͷґଘελοΫ

    View Slide

  39. w Ϣʔβʔ͕௚઀ૢ࡞͢Δ΋ͷͱ͍͏ΑΓ͸ɺ
    3FFL΍$-*πʔϧͳΜ͔Ͱ3VCP$PQͷϊʔ
    υύλʔϯͳͲͷػೳͷΈ࢖͍͍ͨཁ๬͕
    ͋ͬͯ੾Γग़͞Εͨ
    w 5SBWFSTBM 1SPDFTTFE4PVSDF ϊʔυͷύ
    λʔϯهड़ "45֦ுϊʔυ"1*Λఏڙ͢Δ
    3VCP$PQ"45

    View Slide

  40. w 3VCZͷίʔυΛࢦఆ͞Εͨ3VCZόʔδϣϯ
    ʹج͍ͮͯղੳ͞Εͨ
    3VCP$PQ"451SPDFTTFE4PVSDF
    w 1SPDFTTFE4PVSDFBTUͰ"45ΛऔಘՄೳ
    w "45ͷϊʔυछผʹԠͨ͡ίʔϧόοΫΛݺ
    ͼग़͢3VCP$PQ"455SBWFSTBM
    "45Λॲཧ͢Δ͘͠Έ

    View Slide

  41. puts "hello"
    IFMMP αϯϓϧ

    View Slide

  42. require 'rubocop-ast'
    RuboCop::AST::ProcessedSource.new(
    'puts "hello"', 3.1
    )
    3VCP$PQ"451SPDFTTFE4PVSDF

    View Slide

  43. require 'rubocop-ast'
    RuboCop::AST::ProcessedSource.new(
    'puts "hello"', 3.1
    )
    3VCP$PQ"451SPDFTTFE4PVSDF
    w ྫ͑͹"45͸ιʔείϝϯτΛදݱͤͣɺ
    ॲཧ͍ͯ͠Διʔείʔυͦͷ΋ͷͷ৘ใΛ
    ද͢ͷ͕1SPDFTTFE4PVSDFΦϒδΣΫτͰ͢
    w 1SPDFTTFE4PVSDF͸ޙड़͢Δ$PQ ϧʔϧ࣮૷

    ͔Β΋ΞΫηεՄೳͳΦϒδΣΫτͰ͢

    View Slide

  44. require 'rubocop-ast'
    RuboCop::AST::ProcessedSource.new(
    'puts "hello"', 3.1
    )
    ୈҾ਺ͷҙຯ

    View Slide

  45. "[email protected]
    w 3VCZͷόʔδϣϯ͝ͱͷ
    ߏจղੳ͕༻ҙ͞Ε͍ͯΔ
    1BSTFSHFNͷ"1*બఆ͢Δ
    w Ͳͷ3VCZόʔδϣϯͷߏจ
    ΛղੳΛ͢Δ͔ܾΊΔҾ਺
    ʹͳ͍ͬͯΔ

    View Slide

  46. require 'rubocop-ast'
    RuboCop::AST::ProcessedSource.new(
    'puts "hello"', 3.1
    )
    3VCP$PQ"451SPDFTTFE4PVSDF

    View Slide

  47. require 'rubocop-ast'
    ast = RuboCop::AST::ProcessedSource.new(
    'puts "hello"', 3.1
    ).ast
    #=>s(:send, nil, :puts, s(:str, "hello"))
    ast.class
    3VCP$PQ"451SPDFTTFE4PVSDFBTU

    View Slide

  48. require 'rubocop-ast'
    ast = RuboCop::AST::ProcessedSource.new(
    'puts "hello"', 3.1
    ).ast
    #=>s(:send, nil, :puts, s(:str, "hello"))
    ast.class #=> RuboCop::AST::SendNode
    ast.class <= RuboCop::AST::Node # true
    3VCP$PQ"454FOE/PEF

    View Slide

  49. w 1BSTFSఏڙͷ/PEF
    Λܧঝͨ͠ศར"1*
    w 3VCP$PQ"45ͷ
    શϊʔυ͕ܧঝ͢Δ
    εʔύʔΫϥε
    w 3VCP$PQϧʔϧ࣮૷
    ͷࡍʹ౓ʑࢀর͢Δ
    IUUQTHJUIVCDPNSVCPDPQIRSVCPDPQBTUCMPCNBTUFSMJCSVCPDPQBTUOPEFSC
    3VCP$PQ"45/PEF

    View Slide

  50. ast.class #=> RuboCop::AST::SendNode
    ast.source #=> "puts \"hello\""
    ast.location.line #=> 1
    ast.loc.line #=> 1
    ast.loc.column #=> 0
    ast.loc.last_column #=> 12
    ast.loc.source_range #=>
    ast.method_name #=> :puts
    ast.first_argument.basic_literal? #=> true
    3VCP$PQ"454FOE/PEF

    View Slide

  51. 3VCP$PQ"455SBWFSTBM
    require 'rubocop-ast'
    include RuboCop::AST::Traversal
    # Event handler for `send` node
    def on_send(node)
    puts node.source
    end
    walk(ast) #=> puts "hello"

    View Slide

  52. 3VCP$PQ"455SBWFSTBM
    require 'rubocop-ast'
    include RuboCop::AST::Traversal
    # Event handler for `send` node
    def on_send(node)
    puts node.source
    end
    walk(ast) XBML BTU
    ͸ຊฤͰͷݤͰ͢💡

    View Slide

  53. w "45ͷύλʔϯϚον
    Λ͢ΔϛχϚϜݴޠ
    w Ϛονͨ͠஋ΛΩϟϓ
    νϟ͢Δ͜ͱ͕Ͱ͖Δ
    w [email protected]@NBUDIFS
    ͳͲͷҾ਺ʹ࢖ΘΕΔ
    [email protected]UFSOSC
    3VCP$PQ"45/PEF1BUUFSO

    View Slide


  54. ੩తղੳͷ͘͠Έޙฤ

    View Slide

  55. w ղੳର৅ͷ3VCZίʔυͷೖྗͱղੳ݁Ռͷ
    Ϩϙʔτग़ྗ
    w 3VCP$PQͷϧʔϧ࣮૷ͳΒͼʹ֦ு"1*ఏڙ
    w ϢʔβʔͷΧελϜઃఆɺΦϓγϣϯͷղऍ
    w σϑΥϧτϧʔϧ͸SVCZTUZMFHVJEFʹ४ͣΔ
    3VCP$PQ

    View Slide

  56. 3VCP$PQઃܭུ֓
    3VOOFS
    5FBN
    3FHJTUSZ $PQ#BTF
    NPCJMJ[F [email protected]

    %FQU$VTUPN$PQ
    OFX DPEF [email protected]

    OFX
    FOBCMFE
    $PNNJTTJPOFS
    JOWFTUJHBUF [email protected]

    "455SBWFSTBM
    XBML BTU

    NJYJO
    JOWFTUJHBUF [email protected]

    "45
    1SPDFTTFE4PVSDF
    OFX
    OFX DPQT
    [email protected] DBMMCBDL

    EFMFHBUFNFUIPET

    View Slide

  57. 3VCP$PQઃܭུ֓
    3VOOFS
    5FBN
    3FHJTUSZ $PQ#BTF
    NPCJMJ[F [email protected]

    %FQU$VTUPN$PQ
    OFX DPEF [email protected]

    OFX
    FOBCMFE
    $PNNJTTJPOFS
    JOWFTUJHBUF [email protected]

    "455SBWFSTBM
    XBML BTU

    NJYJO
    JOWFTUJHBUF [email protected]

    "45
    1SPDFTTFE4PVSDF
    OFX
    OFX DPQT

    ৭ͳ͠3VCP$PQϥϯλΠϜ
    3VCP$PQ"45
    ϧʔϧ֦ுϙΠϯτ
    [email protected] DBMMCBDL

    EFMFHBUFNFUIPET

    View Slide

  58. wSVCPDPQίϚϯυͷϞδϡʔϧͰ͋
    Δ$-*Ϟδϡʔϧ͔Βݺͼग़͞ΕΔ
    wݕࠪର৅ͷϑΝΠϧύεΛݩʹղੳ
    ͱϧʔϧΛద༻͢Δ಺෦Ϟδϡʔϧ
    ܈Λ૬ޓ࡞༻ͤ͞Δ࣮ߦى఺
    3VOOFS

    View Slide

  59. wϧʔϧΛ࣮૷ͨ͠$PQ͕ొ࿥͞Ε͍ͯ
    ΔΫϥε
    w📝$PQ#BTFͷ$MBTTJOIFSJUFE࣮૷
    ʹΑͬͯɺ͢΂ͯͷ$PQ͸3FHJTUSZʹ
    ొ࿥͞Ε͍ͯΔ ΋ͬͱ͍ܰͨ͘͠

    3FHJTUSZ

    View Slide

  60. wಈһ NPCJMJ[F
    ͞Εͨ$PQΛߏ੒
    ͢ΔΫϥε👮👮👮👮👮
    wΧελϚΠζ͞ΕͨϧʔϧʹԠ͡
    ͨνʔϜ͕૊·ΕΔ
    5FBN

    View Slide

  61. IUUQTHJUIVCDPNSVCPDPQSVCPDPQCMPCNBTUFSMJCSVCPDPQDPQUFBNSC
    5FBN ಈһ

    ༗ޮԽ͞ΕͨϧʔϧͰ͋Δ$PQͷ
    ΫϥεΛ3FHJTUSZ͔Βऔಘͯ͠
    Πϯελϯεੜ੒ͯ͠ฦ͠·͢ɻ
    🚨

    View Slide

  62. IUUQTHJUIVCDPNSVCPDPQSVCPDPQCMPCNBTUFSMJCSVCPDPQDPQUFBNSC
    5FBN ௐࠪ

    ద༻͢Δ$PQͰߏ੒͢Δ
    νʔϜͱߏจղੳͯ͠Δ
    1SPDFTTFE4PVSDFΛݩ
    ʹ$PNNJTTJPOFSΛݺͿ
    🚨
    🔎

    View Slide

  63. w੩తղੳΛऔΓ࢓੾Δॺ௕👮
    wಈһ͞Εͨ$PQͨͪ 5FBN
    ʹΑͬͯ
    ༰ٙऀ ίʔυ
    Λݕࠪ͢Δ
    wͦͷਖ਼ମ͸"455SBWFSTBMΛNJYJOͨ͠
    Ϋϥεɻॺ௕ࣗΒ଍Ͱ૞ࠪ͢Δ XBML

    $PNNJTTJPOFS

    View Slide

  64. $PNNJTTJPOFS ϝλ


    XBMLͰݺͼग़͞ΕΔίʔϧόοΫ
    ϝιουΛϝλϓϩάϥϛϯάͰ
    ఆ͍ٛͯ͠Δ
    IUUQTHJUIVCDPNSVCPDPQSVCPDPQCMPCWMJCSVCPDPQDPQDPNNJTTJPOFSSC

    View Slide

  65. $PNNJTTJPOFS XBML


    JOWFTUJHBUFʹ౉͞Εͨ
    1SPDFTTFE4PVSDFΛ΋ͱʹ͠
    ͨ"45ΛҾ਺ʹXBMLϝιου
    ΛݺͿ
    XBML͔ΒίʔϧόοΫ͞Εͨ
    [email protected]ϝιουͱಉ໊Ͱ$PQʹ
    ఆٛ͞Ε͍ͯΔ[email protected]ʹҠৡ͢Δ
    IUUQTHJUIVCDPNSVCPDPQSVCPDPQCMPCWMJCSVCPDPQDPQDPNNJTTJPOFSSC
    🔎

    View Slide

  66. 3VCP$PQઃܭུ֓ ࠶ܝ

    3VOOFS
    5FBN
    3FHJTUSZ $PQ#BTF
    NPCJMJ[F [email protected]

    %FQU$VTUPN$PQ
    OFX DPEF [email protected]

    OFX
    FOBCMFE
    $PNNJTTJPOFS
    JOWFTUJHBUF [email protected]

    "455SBWFSTBM
    XBML BTU

    NJYJO
    JOWFTUJHBUF [email protected]

    "45
    1SPDFTTFE4PVSDF
    OFX
    OFX DPQT

    ৭ͳ͠3VCP$PQϥϯλΠϜ
    3VCP$PQ"45
    ϧʔϧ֦ுϙΠϯτ
    [email protected] DBMMCBDL

    EFMFHBUFNFUIPET

    View Slide

  67. w$PQͷεʔύΫϥε👮
    wϧʔϧΛ࣮૷͢Δ͢΂ͯͷ$PQ͸
    $PQ#BTFΛܧঝ͢Δ
    w📝$PQ$PQ͸ݹ͍ඇਪ঑ͷεʔύʔΫϥ
    εͳͷͰɺ$PQ#BTFʹߋ৽͠·͠ΐ͏
    $PQ#BTF

    View Slide

  68. w$PQ#BTFΛܧঝ࣮͠ࡍͷϧʔϧΛ࣮૷ͨ͠
    $PQ👮
    w$PQ͸ඞͣԿΒ͔ͷ෦ॺʹॴଐ͢Δ
    wFH4UZMF4USJOH-JUFSBMTDPQ
    w૊ΈࠐΈ$PQͱࣗ࡞$PQͰ࣮૷ͷҧ͍͸ͳ͍
    ΧελϜ$PQ %FQU$VTUPN$PQ

    View Slide

  69. module Cop
    module Style
    class MixinUsage < Base
    MSG = '`%s` is used at the top level.' \
    'Use inside `class` or `module`.'.freeze
    RESTRICT_ON_SEND = %i[include extend prepend].freeze
    def_node_matcher :include_statement, <<~PATTERN
    (send nil? ${:include :extend :prepend} const)
    PATTERN
    def on_send(node)
    return unless (statement = include_statement(node))
    return unless top_level_node?(node)
    add_offense(node, message: format(MSG, statement: statement))
    end
    $PQ ϧʔϧ
    ͷ࣮૷ྫ

    View Slide

  70. ϧʔϧ࣮૷ͷৄࡉ͸ެࣜจॻ΁
    IUUQTEPDTSVCPDPQPSHSVCPDPQEFWFMPQNFOUIUNM

    View Slide

  71. ࣮૷ࣄྫ͸3VCZ,BJHJಈը΁
    IUUQTSVCZLBJHJPSHQSFTFOUBUJPOTLPJDIUNMKVO

    View Slide

  72. "
    ;ͨͭͷόʔδϣϯ

    View Slide

  73. w3VCP$PQͰ͸ɺ3VCZҎ্ͷ੩తղੳ͕ɺ
    3VCZҎ্ͷϥϯλΠϜͰՄೳ
    wϥϯλΠϜཁٻͷ3VCZͷόʔδϣϯ͸3VCP$PQࣗମͷ
    ίʔυ͕ॻ͔ΕͯΔ3VCZόʔδϣϯͰ͋Γ3VCZຊମ͕
    ղੳධՁ͢Δ
    w੩తղੳͷίʔυ͸1BSTFSHFNͰղੳ͢Δ
    wSVCPDPQZNMͷ5BSHFU3VCZ7FSTJPOͰWFSTJPOࢦఆՄ
    ղੳόʔδϣϯͱ࣮ߦόʔδϣϯ

    View Slide

  74. 4VQQPSUNBUSJY W


    ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌
    ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌
    ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌
    ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌
    ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌
    ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌
    ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌
    ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌
    ❌ ❌ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅
    ❌ ❌ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅
    ❌ ❌ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅
    ❌ ❌ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅
    ❌ ❌ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅
    "OBMZTJT3VCZWFSTJPOT TargetRubyVersionJOSVCPDPQZNM

    3VOUJNF3VCZWFSTJPOT
    ruby -v

    View Slide

  75. 3VCZͰ3VCZΛղੳ͢Δ
    ࣈ۟ղੳ ߏจղੳ ੩తղੳ
    Ϩϙʔτ
    ιʔείʔυ
    ೖྗ
    ॲཧ
    ग़ྗ
    3VCZॲཧܥͷղੳධՁ
    3BDDʹΑΔߏจղੳ

    View Slide

  76. lίʔυΛখઆͷΑ͏ʹಡΜͰɺ
    ಠ૑తͳےॻ͖΍ࢥ͍΋ΑΒ͵ن
    ଇੑΛָ͠Έ·͠ΐ͏ɻҰݟඇৗ
    ʹෳࡶͳ΋ͷΛίϯύΫτͰΤϨ
    Ψϯτͳߏ଄Ͱ࣮ݱ͍ͯ͠Δ΋ͷ
    Λݟ͚ͭΔ͜ͱ΋͋Ε͹ɺখઆͳ
    ͕ΒوॏͳๅੴͷΑ͏ͳίʔυΛ
    ݟ͚ͭΔ͜ͱ΋͋Γ·͢ɻz
    $PEF3FBEJOH

    View Slide