Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

@koic w044ϓϩάϥϚʔ w3VCP$PQίΞνʔϜ wגࣜձࣾӬ࿨γεςϜϚωδϝϯτ &4. *OD ΤϯδχΞϦϯάϚωʔδϟʔ݉ σΟεςΟϯάΠογϡυΤϯδχΞ

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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 +++++++++++++

Slide 8

Slide 8 text

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 +++++++++++++ 👈

Slide 9

Slide 9 text

UI"OOJWFSTBSZZFBS🎉

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

.F

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

ߏจղੳͷ͘͠Έ

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

% 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͕ੜ੒͞ΕΔ

Slide 24

Slide 24 text

3VCZ͔Β1BSTFS΁ͷҠ২ྫ

Slide 25

Slide 25 text

XIJUFRVBSLQBSTFS SVCZZ"MMPXUSBJMJOHDPNNBJOIBTIQBUUFSO

Slide 26

Slide 26 text

DEdTSDHJUIVCDPNSVCZSVCZ HJUMPHQQBSTFZ DPNNJUEBGEDFBEBCBBGCBDDF "VUIPS,B[VLJ5TVKJNPUPLB[VLJ!DBMMDDOFU %BUF4VO.BS "MMPXUSBJMJOHDPNNBJOIBTIQBUUFSO EJ⒎HJUBQBSTFZCQBSTFZ JOEFYDDGCG BQBSTFZ CQBSTFZ !! !!Q@LXBSHTQ@LXBSH Q@LXSFTU \ OFX@IBTI@QBUUFSO@UBJM Q OFX@VOJRVF@LFZ@IBTI Q ! ! ^ 3VCZͷQBSTFZ

Slide 27

Slide 27 text

IUUQTHJUIVCDPNSVCZSVCZDPNNJUEBG

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

3VCZ͔Β1BSTFSʹҠ২

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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͸ಉ͡

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

੩తղੳͷ͘͠Έલฤ

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

puts "hello" IFMMP αϯϓϧ

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

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"

Slide 52

Slide 52 text

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 ͸ຊฤͰͷݤͰ͢💡

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

੩తղੳͷ͘͠Έޙฤ

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

3VCP$PQઃܭུ֓ 3VOOFS 5FBN 3FHJTUSZ $PQ#BTF NPCJMJ[F DPQ@DMBTTFT %FQU$VTUPN$PQ OFX DPEF SVCZ@WFSTJPO OFX FOBCMFE $PNNJTTJPOFS JOWFTUJHBUF QSPDFTTFE@TPVSDF "455SBWFSTBM XBML BTU NJYJO JOWFTUJHBUF QSPDFTTFE@TPVSDF "45 1SPDFTTFE4PVSDF OFX OFX DPQT PO@YYY DBMMCBDL EFMFHBUFNFUIPET

Slide 57

Slide 57 text

3VCP$PQઃܭུ֓ 3VOOFS 5FBN 3FHJTUSZ $PQ#BTF NPCJMJ[F DPQ@DMBTTFT %FQU$VTUPN$PQ OFX DPEF SVCZ@WFSTJPO OFX FOBCMFE $PNNJTTJPOFS JOWFTUJHBUF QSPDFTTFE@TPVSDF "455SBWFSTBM XBML BTU NJYJO JOWFTUJHBUF QSPDFTTFE@TPVSDF "45 1SPDFTTFE4PVSDF OFX OFX DPQT ৭ͳ͠3VCP$PQϥϯλΠϜ 3VCP$PQ"45 ϧʔϧ֦ுϙΠϯτ PO@YYY DBMMCBDL EFMFHBUFNFUIPET

Slide 58

Slide 58 text

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

Slide 59

Slide 59 text

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

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

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

Slide 64

Slide 64 text

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

Slide 65

Slide 65 text

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

Slide 66

Slide 66 text

3VCP$PQઃܭུ֓ ࠶ܝ 3VOOFS 5FBN 3FHJTUSZ $PQ#BTF NPCJMJ[F DPQ@DMBTTFT %FQU$VTUPN$PQ OFX DPEF SVCZ@WFSTJPO OFX FOBCMFE $PNNJTTJPOFS JOWFTUJHBUF QSPDFTTFE@TPVSDF "455SBWFSTBM XBML BTU NJYJO JOWFTUJHBUF QSPDFTTFE@TPVSDF "45 1SPDFTTFE4PVSDF OFX OFX DPQT ৭ͳ͠3VCP$PQϥϯλΠϜ 3VCP$PQ"45 ϧʔϧ֦ுϙΠϯτ PO@YYY DBMMCBDL EFMFHBUFNFUIPET

Slide 67

Slide 67 text

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

Slide 68

Slide 68 text

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

Slide 69

Slide 69 text

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 ϧʔϧ ͷ࣮૷ྫ

Slide 70

Slide 70 text

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

Slide 71

Slide 71 text

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

Slide 72

Slide 72 text

" ;ͨͭͷόʔδϣϯ

Slide 73

Slide 73 text

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

Slide 74

Slide 74 text

4VQQPSUNBUSJY W ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ❌ ❌ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ❌ ❌ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ❌ ❌ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ❌ ❌ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ "OBMZTJT3VCZWFSTJPOT TargetRubyVersionJOSVCPDPQZNM 3VOUJNF3VCZWFSTJPOT ruby -v

Slide 75

Slide 75 text

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

Slide 76

Slide 76 text

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