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

Improve Ruby coding styles and Lint

Improve Ruby coding styles and Lint

RubyKaigi 2018
http://rubykaigi.org/2018

Koichi ITO

June 01, 2018
Tweet

More Decks by Koichi ITO

Other Decks in Programming

Transcript

  1. 'SJ

    Improve Ruby coding
    style rules and Lint
    ,PJDIJ*50FTN
    3VCZ,BJHJ
    4FOEBJ*OUFSOBUJPOBM$FOUFS)BHJ
    How do you join social coding?

    View full-size slide

  2. QPTJUJPOUBML

    View full-size slide

  3. :PVNBZLOPX
    BGBNPVTMBSHF
    044DPNNVOJUZ

    View full-size slide

  4. w*NQSPWFUFTUDPWFSBHFGPS0SBDMF
    FOIBODFEBEBQUFS
    w*OUSPEVDF'SP[FO4USJOH-JUFSBMT
    w4VQQSFTTXBSOJOHTXJUI&EHF3VCZ
    w*NQPSUFYQPSU3VCP$PQ
    DPOpHVSBUJPOT
    w/JUQJDLTBOETPPO
    .ZXPSLTJO3BJMT

    View full-size slide

  5. 3BJMTDPNNVOJUZ
    JTPOFPGIPNF
    JONZIFBSU

    View full-size slide

  6. *PGUFOIBWFBDUJWJUJFT
    JO3VCP$PQSFDFOUMZ

    View full-size slide

  7. w'JYCVHT
    w$SFBUFOFXDPQT
    w*NQSPWFEPDVNFOUT
    w*NQSPWFJOUFSOBMBGGBJST
    w.BJOUFOBODF$*DPOEJUJPOT
    .ZXPSLTJO3VCP$PQ

    View full-size slide

  8. w%JSFDUJPOPGB3BJMTBQQQSPKFDU
    w6QHSBEJOH3VCZ3BJMTGPSBQQT
    BOETVSSPVOEJOHHFNT
    w0SHBOJ[F3BJMT044QBUDI
    NFFUVQTJOFTN
    w3FDSVJUJOHJOUFSWJFXFS
    .ZXPSLTJOFTN

    View full-size slide

  9. "TUPSZBGUFSZFBST
    GSPNBNFNPSJBM
    QSFTFOUBUJPOJO
    5PEBZ`TUBML

    View full-size slide

  10. 8IBUIBQQFOFE
    JO

    View full-size slide

  11. IUUQKQSVCZJTUOFU3VCZ,BJHJ DQMVHJOQMVHJOBUUBDI@EPXOMPBEQ1SPHSBNpMF@OBNFUIF@JTMBOE@PG@SVCZ@KQEG
    3VCZ,BJHJ
    %BWF5IPNBT

    View full-size slide

  12. w7BSJPVTDPNQBOJFTVTJOH3VCZ
    3BJMTGPSEFWFMPQNFOUBQQFBSFE
    w(JU)VCIBTBQQFBSFE BOE
    JOEJWJEVBMBDUJWJUJFTBSFESBXJOH
    BUUFOUJPO
    w3VCZJTUTBOE3VCZJTIDPNQBOJFT
    NBLFWBSJPVT3VCZDPEJOHTUZMFT
    .PEFSOUJNFT

    View full-size slide

  13. 5IFSFBSFWBSJPVT
    3VCZDPEJOHTUZMFT
    %JWFSTJUZ

    View full-size slide

  14. "3VCZDPEF
    def badName
    if something
    test
    end
    end

    View full-size slide

  15. 3VOXJUIUIFEFGBVMU
    3VCP$PQTFUUJOH

    View full-size slide

  16. %FQBSU/BNF$PQ/BNF%FTDSJQUJPO

    View full-size slide

  17. 3VCP$PQIBTTFWFSBM
    EFQBSUNFOUT

    View full-size slide

  18. 0GpDJBMNBOVBM

    View full-size slide

  19. -BZPVU%FQBSUNFOU
    "MJHO"SSBZ
    .FUBQIFS
    "MJHO)BTI
    &MTF"MJHONFOU
    &NQUZ-JOFT
    &OE"MJHONFOU
    &YUSB4QBDJOH
    *OEFOU"SSBZ
    -JOU%FQBSUNFOU
    %VQMJDBUF.FUIPET
    %VQMJDBUFE,FZ
    &MTF"MJHONFOU
    4DSJQU1FSNJTTJPO
    6OJpFE*OUFHFS
    6OSFBDIBCMF$PEF
    6OMFTT"TTJHONFOU
    .FUSJDT%FQBSUNFOU
    "CD4J[F
    #MPDL-FOHUI
    #MPDL/FTUJOH
    $MBTT-FOHUI
    -JOF-FOHUI
    .FUIPE-FOHUI
    1BSBNFUFS-JTUT
    ʜ

    View full-size slide

  20. %FQBSU/BNF$PQ/BNF%FTDSJQUJPO

    View full-size slide

  21. 3VCP$PQIBTNBOZlCVJMUJODPQTz
    BOElDVTUPNDPQTzZPVDBOBEECZVTJOH
    QMVHHBCMFNFDIBOJTN

    View full-size slide

  22. /FXDPQ
    NBEFCZNF

    View full-size slide

  23. $SFBUJPODPQDPVOU
    QXE
    6TFSTLPJDTSDHJUIVCDPNSVCPDPQIRSVCPDPQ
    DBU$)"/(&-0(NEcHSFQLPJDcHSFQJBEEOFXcXDM

    View full-size slide

  24. $SFBUJPODPQDPVOU
    QXE
    6TFSTLPJDTSDHJUIVCDPNSVCPDPQIRSVCPDPQ
    DBU$)"/(&-0(NEcHSFQLPJDcHSFQJBEEOFXcXDM

    View full-size slide

  25. $SFBUJPODPQDPVOU
    QXE
    6TFSTLPJDTSDHJUIVCDPNSVCPDPQIRSVCPDPQ
    DBU$)"/(&-0(NEcHSFQLPJDcHSFQJBEEOFXcXDM

    DBU$)"/(&-0(NEcHSFQQPDLFcHSFQJBEEOFXcXDM

    View full-size slide

  26. $SFBUJPODPQDPVOU
    QXE
    6TFSTLPJDTSDHJUIVCDPNSVCPDPQIRSVCPDPQ
    DBU$)"/(&-0(NEcHSFQLPJDcHSFQJBEEOFXcXDM

    DBU$)"/(&-0(NEcHSFQQPDLFcHSFQJBEEOFXcXDM

    DBU$)"/(&-0(NEcHSFQESFONJcHSFQJBEEOFXcXDM

    View full-size slide

  27. $SFBUJPODPQDPVOU
    QXE
    6TFSTLPJDTSDHJUIVCDPNSVCPDPQIRSVCPDPQ
    DBU$)"/(&-0(NEcHSFQLPJDcHSFQJBEEOFXcXDM

    DBU$)"/(&-0(NEcHSFQQPDLFcHSFQJBEEOFXcXDM

    DBU$)"/(&-0(NEcHSFQESFONJcHSFQJBEEOFXcXDM

    DBU$)"/(&-0(NEcHSFQCCBUTPWcHSFQJBEEOFXcXDM

    View full-size slide

  28. -JTUPGDPQT*DSFBUFE

    DBU$)"/(&-0(NEcHSFQLPJDcHSFQJBEEOFX
    <> IUUQTHJUIVCDPNCCBUTPWSVCPDPQQVMM
    "EE
    OFXA3BJMT3FGVUF.FUIPETADPQ <>

    <> IUUQTHJUIVCDPNCCBUTPWSVCPDPQQVMM
    "EE
    OFXA-JOU&SC/FX"SHVNFOUTADPQ <>

    <> IUUQTHJUIVCDPNCCBUTPWSVCPDPQQVMM
    "EE
    OFXA-JOU#JH%FDJNBM/FXADPQ <>

    <> IUUQTHJUIVCDPNCCBUTPWSVCPDPQJTTVFT

    "EEOFXA-BZPVU&NQUZ$PNNFOUADPQ <>

    <> IUUQTHJUIVCDPNCCBUTPWSVCPDPQJTTVFT

    "EEOFXA-JOU0SEFSFE.BHJD$PNNFOUTADPQ <>

    <> IUUQTHJUIVCDPNCCBUTPWSVCPDPQJTTVFT

    "EEOFXA4UZMF&YQBOE1BUI"SHVNFOUTADPQ <>

    View full-size slide

  29. -JTUPGDPQT*DSFBUFE

    <> IUUQTHJUIVCDPNCCBUTPWSVCPDPQQVMM
    "EE
    OFXA(FNTQFD3FRVJSFE3VCZ7FSTJPOADPQ <>

    <> IUUQTHJUIVCDPNCCBUTPWSVCPDPQQVMM
    "EE
    OFXA(FNTQFD3FEVOEBOU"TTJHONFOUADPQ <>

    <> IUUQTHJUIVCDPNCCBUTPWSVCPDPQQVMM
    "EE
    OFXA3BJMT3FEVOEBOU3FDFJWFS*O8JUI0QUJPOTADPQ <>

    <> IUUQTHJUIVCDPNCCBUTPWSVCPDPQJTTVFT

    "EEOFXA-JOU6OOFFEFE3FRVJSF4UBUFNFOUADPQ <>

    <> IUUQTHJUIVCDPNCCBUTPWSVCPDPQQVMM
    "EE
    OFXA4UZMF4UEFSS1VUTADPQ <>

    <> IUUQTHJUIVCDPNCCBUTPWSVCPDPQQVMM
    "EE
    OFXA-JOU3FEVOEBOU8JUI0CKFDUADPQ <>

    View full-size slide

  30. -JTUPGDPQT*DSFBUFE

    <> IUUQTHJUIVCDPNCCBUTPWSVCPDPQQVMM
    "EE
    OFXA4UZMF.JYJO6TBHFADPQ <>

    <> IUUQTHJUIVCDPNCCBUTPWSVCPDPQQVMM
    "EE
    OFXA-JOU6SJ&TDBQF6OFTDBQFADPQ <>

    <> IUUQTHJUIVCDPNCCBUTPWSVCPDPQQVMM
    "EE
    OFXA1FSGPSNBODF6SJ%FGBVMU1BSTFSADPQ <>

    <> IUUQTHJUIVCDPNCCBUTPWSVCPDPQQVMM
    "EE
    OFXA-JOU6SJ3FHFYQADPQ <>

    <> IUUQTHJUIVCDPNCCBUTPWSVCPDPQQVMM
    "EE
    OFXA#VOEMFS*OTFDVSF1SPUPDPM4PVSDFADPQ <>

    <> IUUQTHJUIVCDPNCCBUTPWSVCPDPQQVMM
    "EE
    OFXA-JOU3FEVOEBOU8JUI*OEFYADPQ <>

    View full-size slide

  31. -JTUPGDPQT*DSFBUFE

    "EEOFXA1FSGPSNBODF4PSU8JUI#MPDLADPQUPVTF
    ATPSU@CZ GPP
    AJOTUFBEPGATPSU\cB CcBGPPCGPP^A
    <>

    View full-size slide

  32. /VNCFSPG
    PQQPSUVOJUJFTUP
    NBLFDPQT
    ()SVCPDPQIRSVCPDPQ

    View full-size slide

  33. /VNCFSPG
    PQQPSUVOJUJFTUP
    NBLFDPQT
    ()SVCPDPQIRSVCPDPQ
    3VCZ


    View full-size slide

  34. /VNCFSPG
    PQQPSUVOJUJFTUP
    NBLFDPQT
    ()SVCPDPQIRSVCPDPQ
    3VCZ
    .ZQSPKFDUT



    View full-size slide

  35. /VNCFSPG
    PQQPSUVOJUJFTUP
    NBLFDPQT
    ()SVCPDPQIRSVCPDPQ
    3VCZ
    .ZQSPKFDUT
    ()SBJMTSBJMT




    View full-size slide

  36. -FUTUBMLBCPVUUIFCBDLHSPVOEPG
    NBLJOHUIFTFDPQTBOEUIF
    LOPXMFEHFHBJOFEJOUIBUQSPDFTT

    View full-size slide

  37. 'SJ

    Improve Ruby coding
    style rules and Lint
    ,PJDIJ*50FTN
    3VCZ,BJHJ
    4FOEBJ*OUFSOBUJPOBM$FOUFS)BHJ
    How do you join social coding?

    View full-size slide

  38. "HFOEB
    0OUIFEJGGFSFODF
    CFUXFFODPEJOHTUZMFBOE
    -JOU &NVMBUF3VCZ`TXBSOJOH

    /FXDPQTUBSUTXJUI

    ZPVSQSPKFDU
    $SPTTPWFS

    044DPNNVOJUJFT
    1BSU
    1BSU
    1BSU

    View full-size slide

  39. 0OUIFEJGGFSFODF
    CFUXFFODPEJOH
    TUZMFBOE-JOU

    View full-size slide

  40. w4UZMFJTGSPN
    WBSJPVTDVMUVSFT
    w6OJpFEXJUIJOB
    QSPKFDUTQFDJpD
    UBTUF
    4UZMF

    View full-size slide

  41. 5IFSFT.PSF5IBO
    0OF8BZ5P

    %FpOFB4UZMF

    View full-size slide

  42. w.JOFSP"PLJTDPEJOHTUZMF +"

    wIUUQJMPWFSVCZOFUKBSVCZDPEJOHTUZMFIUNM
    w4IVHP.BFEBTDPEJOHTUZMF +"

    wIUUQTTIVHPOFUSVCZDPEFDPOW
    DPEFDPOWIUNM
    w3VCZ4UZMF(VJEF
    wIUUQTHJUIVCDPNSVCPDPQIRSVCZTUZMFHVJEF
    w"OEPUIFSTUZMFT
    w1FSTPOBMBOE$PNQBOZDPEJOHTUZMFT
    .BOZTUZMFTJOUIFSFBMXPSME

    View full-size slide

  43. 3VCZ4UZMF(VJEF

    View full-size slide

  44. w3VCP$PQJNQMFNFOUT
    3VCZ4UZMF(VJEFCZ
    EFGBVMU
    w3VCP$PQTPNFUJNFT
    QSPWJEFTPQUJPOT
    4UZMFPG3VCP$PQ

    View full-size slide

  45. &OGPSDFE4UZMFJTBOPQUJPOQBSBNFUFS
    IUUQSVCPDPQSFBEUIFEPDTJPFOMBUFTUDPQT@MBZPVUMBZPVUTQBDFJOTJEFCMPDLCSBDFT

    View full-size slide

  46. &OGPSDFE4UZMFJTBOPQUJPOQBSBNFUFS
    IUUQSVCPDPQSFBEUIFEPDTJPFOMBUFTUDPQT@MBZPVUMBZPVUTQBDFJOTJEFCMPDLCSBDFT
    HPPE
    TPNF@BSSBZFBDI\cFcQVUTF^

    View full-size slide

  47. &OGPSDFE4UZMFJTBOPQUJPOQBSBNFUFS
    IUUQSVCPDPQSFBEUIFEPDTJPFOMBUFTUDPQT@MBZPVUMBZPVUTQBDFJOTJEFCMPDLCSBDFT
    HPPE
    TPNF@BSSBZFBDI\cFcQVUTF^
    HPPE
    TPNF@BSSBZFBDI\cFcQVUTF^

    View full-size slide

  48. w*GZPVEPOPUMJLFUIFEFGBVMUTUZMF
    UIBUJT UIFTFUUJOHPGl3VCZ4UZMF
    (VJEFz
    ZPVDBOUBLFUIF
    GPMMPXJOHPQUJPOT
    w&EJUSVCPDPQZNMBOEVTF
    EJGGFSFOUPQUJPOT
    w&EJUSVCPDPQZNMBOEDIBOHFUIJT
    DPQ
    :PVDBODVTUPNJ[FUIFXBZ

    View full-size slide

  49. $VTUPNJ[FECZSVCPDPQZNM
    "MM$PQT
    5BSHFU3VCZ7FSTJPO
    -BZPVU4QBDF*OTJEF#MPDL4QBDFT
    &OGPSDFE4UZMFOP@TQBDF
    $IBOHF&OGPSDFE4UZMFGSPN
    TQBDF EFGBVMU
    UPOP@TQBDF

    View full-size slide

  50. w%PO`UCFBGSBJEPGDVTUPNJ[BUJPO
    w1MFBTFCFDPOpEFOUJOZPVS
    DVMUVSF
    w*GFJUIFSJTPLBZUIFEFGBVMUXJMM
    CFpOF
    w"TBQFSTPOBMPQJOJPO UIFSFJT
    OPVOJpFE$P$JO4UZMF
    %FGBVMUJTOPUUIFPOMZTFUUJOH

    View full-size slide

  51. w%FGBVMUDPOpHVSBUJPO
    CBTFEPO3VCZ4UZMF
    (VJEF
    w:PVNBZCFBCMFUP
    DIBOHF3VCP$PQ
    DPOpHVSBUJPO
    :PVDBODPOpHVSF3VCP$PQVTJOH
    SVCPDPQZNM

    View full-size slide

  52. w'PSFYBNQMF UBMLCZ,FJKV
    *TIJ[VLBTBOBUPFEPSC
    w5IFEJGGFSFODFCFUXFFO
    `do``end`BOE`{``}`
    w3FQSFTFOUTUBUFNFOUBOE
    FYQSFTTJPOSFTQFDUJWFMZ
    5IFSFNBZOPUCFPQUJPOTZPVMJLF

    View full-size slide

  53. w%PFTUIFDPQEFDJEFXIFUIFSZPV
    BSFVTJOHSFUVSOWBMVFPSNFUIPE
    DIBJO
    w%PFTUIFDPQBMTPXPSLXIFO
    NVMUJQMZJOHUIFXIJUFMJTUPGNFUIPE
    OBNFT
    w3VCZCMPDLrescueJTBWBJMBCMFGPS
    `do``end`POMZ
    *UMFBETUPQBSUPGEFTJHOPG

    BOVOJNQMFNFOUFEDPQ

    View full-size slide

  54. w5IJOHTUIBUIBWFQPUFOUJBM
    CVHT
    w%FQSFDBUJPOXBSOJOHEVFUP
    GVUVSFJOUFSGBDFDIBOHF
    w3VCP$PQEPFTOPUQSPWJEF
    NBOZPQUJPOTPG-JOU
    -JOU

    View full-size slide

  55. /FX-JOUDPQ
    GPS3VCZ
    &YBNQMFT

    View full-size slide

  56. *NQPSUXBSOJOHT
    GSPNSVCZSVCZUP
    3VCP$PQ
    ()SVCPDPQIRSVCPDPQ
    VQTUSFBN
    3VCZXBSOJOHT

    View full-size slide

  57. SVCPDPQIRSVCPDPQ
    "EEOFXA-JOU&SC/FX"SHVNFOUTADPQ

    View full-size slide

  58. "4UEMJCVQEBUF
    IUUQTHJUIVCDPNSVCZSVCZCMPCCFEDGGBGDGDB/&84TUEMJCVQEBUFTPVUTUBOEJOHPOFTPOMZ

    View full-size slide

  59. &3#OFXJO3VCZ
    % cat example.rb
    require ‘erb'
    ERB.new('hi', nil, '-', ‘@output_buffer')

    View full-size slide

  60. &3#OFXJO3VCZ
    % cat example.rb
    require ‘erb'
    ERB.new('hi', nil, '-', ‘@output_buffer')
    % ruby example.rb
    example.rb:3: warning: Passing safe_level with the
    2nd argument of ERB.new is deprecated. Do not use it,
    and specify other arguments as keyword arguments.
    example.rb:3: warning: Passing trim_mode with the 3rd
    argument of ERB.new is deprecated. Use keyword
    argument like ERB.new(str, trim_mode: ...) instead.
    example.rb:3: warning: Passing eoutvar with the 4th
    argument of ERB.new is deprecated. Use keyword
    argument like ERB.new(str, eoutvar: ...) instead.

    View full-size slide

  61. &3#OFXJO3VCZ
    # bad
    # ERB.new(str, nil, '-', '@output_buffer')
    # good
    # ERB.new(str, trim_mode: '-', eoutvar:'@output_buffer')

    View full-size slide

  62. 3VCZ$PNQBUJCMF
    # https://github.com/ruby/ruby/commit/3406c5d
    # Ruby 2.6+
    if ERB.instance_method(:initialize).parameters.assoc(:key)
    ERB.new(str, trim_mode: '-', eoutvar: '@output_buffer')
    else
    ERB.new(str, nil, '-', '@output_buffer')
    end

    View full-size slide

  63. NJOJNVN@UBSHFU@SVCZ@WFSTJPO

    View full-size slide

  64. &NVMBUJPOPG3VCP$PQ
    % rubocop example.rb --only Lint/ErbNewArguments
    Inspecting 1 file
    W
    Offenses:
    example.rb:3:15: W: Lint/ErbNewArguments: Passing safe_level with
    the 2nd argument of ERB.new is deprecated. Do not use it, and
    specify other arguments as keyword arguments.
    ERB.new('hi', nil, '-', '@output_buffer')
    ^^^
    example.rb:3:20: W: Lint/ErbNewArguments: Passing trim_mode with
    the 3rd argument of ERB.new is deprecated. Use keyword argument
    like ERB.new(str, trim_mode: '-') instead.
    ERB.new('hi', nil, '-', '@output_buffer')
    ^^^
    example.rb:3:25: W: Lint/ErbNewArguments: Passing eoutvar with the
    4th argument of ERB.new is deprecated. Use keyword argument like
    ERB.new(str, eoutvar: '@output_buffer') instead.
    ERB.new('hi', nil, '-', '@output_buffer')
    ^^^^^^^^^^^^^^^^

    View full-size slide

  65. %JEZPVIBWFBOZQSPCMFNT

    View full-size slide

  66. FSJLIVEBUIPS
    %FQSFDBUFTBGF@MFWFMPG&3#OFXJO3VCZ

    View full-size slide

  67. 5IFMPHMFOHUIIBTFYDFFEFEUIF
    MJNJUPG.#
    IUUQTHJUIVCDPNFSJLIVEBUIPSQVMMJTTVFDPNNFOU

    View full-size slide

  68. wruby -w (RUBYOPT='-w')PQUJPOUSBDFT
    XBSOJOHTJOEFQFOEFOUMJCSBSJFT
    w3VCP$PQ`THSBOVMBSJUZJTSFQPTJUPSZ
    ZPVDBOGPDVTPOZPVS3BJMT
    BQQMJDBUJPODPEFBOEXBSOJOHTPO
    MJCSBSJFTUIBUZPVBSFNBOBHJOH
    w:PVDBOTVQFSJNQPTFQSFFYFDVUJPO
    XBSOJOHBOESVOUJNFXBSOJOH
    ASVCZXAPQUJPOWT3VCP$PQ

    View full-size slide

  69. w.PTUMZ-JOUNBZCFFOBCMFE
    CFDBVTFJUJTOPUBQSFGFSFODF
    CVUBMBOHVBHFTQFDJpDBUJPO
    w*UJTCFUUFSOPUUPCFBGSBJEUP
    DIBOHFUIFTUZMFUIBUEPFT
    OPUpUUIFDVMUVSF5IFSFBSF
    WBSJPVTQSFGFSFODFT
    $PODMVTJPO

    View full-size slide

  70. "HFOEB
    0OUIFEJGGFSFODF
    CFUXFFODPEJOHTUZMFBOE
    -JOU &NVMBUF3VCZ`TXBSOJOH

    /FXDPQTUBSUTXJUI

    ZPVSQSPKFDU
    $SPTTPWFS

    044DPNNVOJUJFT
    1BSU
    1BSU
    1BSU

    View full-size slide

  71. /FXDPQ
    TUBSUTXJUI
    ZPVSQSPKFDU

    View full-size slide

  72. 8FBSFDPOOFDUFECZ044
    VQTUSFBN
    ()SVCPDPQIRSVCPDPQ
    .ZQSPKFDU
    ZPVSQSPKFDU
    w"TUPSZXIFSFDPEFSFWJFXT
    JONZQSPKFDUBSFDPEF
    SFWJFXTJOZPVSQSPKFDU

    View full-size slide

  73. SVCPDPQIRSVCPDPQ
    "EEOFXA4UZMF.JYJO6TBHFADPQ

    View full-size slide

  74. "3BJMTBQQMJDBUJPO
    EFWFMPQNFOU

    View full-size slide

  75. 3FWJFXDPNNFOU
    *ODMVEJOHBUUIJTQPTJUJPOXJMMUBJOUUIFUPQMFWFM
    3JHIU*XJMMpYJU

    View full-size slide

  76. 8IBUZPVQPJOUFEPVU
    DBOCFQPJOUFEPVUBU
    PUIFSPQQPSUVOJUJFT

    View full-size slide

  77. 044
    3JEFPO044
    3JEFPO044

    View full-size slide

  78. "DPQ*NBEFIFMQFE
    FWFOJONZGSJFOET
    QSPKFDU

    View full-size slide

  79. !POLTBZT
    l
    4UZMF.JYJO6TBHFDPQ

    IBTXPSLFE 

    TP*TIPVMEHJWF!LPJD
    IUUQTUXJUUFSDPNPOLTUBUVT

    View full-size slide

  80. )PXUPNBLF4UZMF.JYJO6TFHFDPQ

    View full-size slide

  81. SBLFOFX@DPQ
    % be rake new_cop[Rails/TopLevelInclude]

    View full-size slide

  82. SBLFOFX@DPQ
    % be rake new_cop[Rails/TopLevelInclude]
    Files created:
    - lib/rubocop/cop/rails/top_level_include.rb
    - spec/rubocop/cop/rails/
    top_level_include_spec.rb
    File modified:
    - `require_relative 'rubocop/cop/rails/
    top_level_include'` added into lib/rubocop.rb
    Do 3 steps:
    1. Add an entry to the "New features" section in
    CHANGELOG.md,
    e.g. "Add new `TopLevel/Include` cop.
    ([@your_id][])"
    2. Add an entry into config/enabled.yml or
    config/disabled.yml
    3. Implement your new cop in the generated file!

    View full-size slide

  83. 8SJUFFYBNQMFT
    # TODO: when finished, run `rake
    generate_cops_documentation` to update the docs
    module RuboCop
    module Cop
    module Rails
    # TODO: Write cop description and example of
    bad / good code.
    #
    # @example
    # # bad
    # bad_method()
    #
    # # good
    # bad_method(args)
    8SJUFDPQEFTDSJQUJPOBOE
    FYBNQMFPGCBEHPPE

    View full-size slide

  84. 8SJUFTQFDT
    describe RuboCop::Cop::Rails::TopLevelInclude do
    it 'registers an offense when using `#bad_method`'
    do
    expect_offense(<<-RUBY.strip_indent)
    bad_method
    ^^^^^^^^^^ Use `#good_method` instead of
    `#bad_method`.
    RUBY
    end
    it 'does not register an offense when using
    `#good_method`' do
    expect_no_offenses(<<-RUBY.strip_indent)
    good_method
    RUBY
    end
    end
    8SJUFBCBEDBTFPOUIFAFYQFDU@P⒎FOTFA
    NFUIPE

    View full-size slide

  85. 8SJUFTQFDT
    describe RuboCop::Cop::Rails::TopLevelInclude do
    it 'registers an offense when using `#bad_method`'
    do
    expect_offense(<<-RUBY.strip_indent)
    bad_method
    ^^^^^^^^^^ Use `#good_method` instead of
    `#bad_method`.
    RUBY
    end
    it 'does not register an offense when using
    `#good_method`' do
    expect_no_offenses(<<-RUBY.strip_indent)
    good_method
    RUBY
    end
    end
    8SJUFBCBEDBTFPOUIFAFYQFDU@P⒎FOTFA
    NFUIPE
    8SJUFBHPPEDBTFPOUIFAFYQFDU@OP@P⒎FOTFTA
    NFUIPE

    View full-size slide

  86. w8JUIexpect_offense
    BOE
    expect_no_offenses
    UIFUFTUDBOCF
    XSJUUFOSPVHIMZ
    4USPOHUFTUJOH%4-

    View full-size slide

  87. 8SJUFTQFDT BHBJO

    describe RuboCop::Cop::Rails::TopLevelInclude do
    it 'registers an offense when using `#bad_method`' do
    expect_offense(<<-RUBY.strip_indent)
    bad_method
    ^^^^^^^^^^ Use `#good_method` instead of
    `#bad_method`.
    RUBY
    end
    it 'does not register an offense when using
    `#good_method`' do
    expect_no_offenses(<<-RUBY.strip_indent)
    good_method
    RUBY
    end
    end
    8SJUFBCBEDBTFPOUIFAFYQFDU@P⒎FOTFA
    NFUIPE
    8SJUFBHPPEDBTFPOUIFAFYQFDU@OP@P⒎FOTFTA
    NFUIPE

    View full-size slide

  88. 3FXSJUFTQFDT
    describe RuboCop::Cop::Rails::TopLevelInclude do
    it 'registers an offense when using outside class' do
    expect_offense(<<-RUBY.strip_indent)
    include
    ^^^^^^^ `include` is used at the top level. Use
    inside `class` or `module`.
    class C
    end
    RUBY
    end
    8SJUFBCBEDBTFPOUIFAFYQFDU@P⒎FOTFA
    NFUIPE

    View full-size slide

  89. 3FXSJUFTQFDT
    describe RuboCop::Cop::Rails::TopLevelInclude do
    it 'registers an offense when using outside class' do
    expect_offense(<<-RUBY.strip_indent)
    include
    ^^^^^^^^^ `include` is used at the top level. Use
    inside `class` or `module`.
    class C
    end
    RUBY
    end
    it 'does not register an offense when using inside
    class' do
    expect_no_offenses(<<-RUBY.strip_indent)
    class C
    include M
    end
    RUBY
    8SJUFBHPPEDBTFPOUIFAFYQFDU@OP@P⒎FOTFTA
    NFUIPE

    View full-size slide

  90. SVCZQBSTF
    % ruby-parse -e 'include M’
    (send nil :include
    (const nil :M))
    % ruby-parse -e 'extend M’
    (send nil :extend
    (const nil :M))
    % ruby-parse -e 'prepend M’
    (send nil :prepend
    (const nil :M))
    (FU4FYQSFTTJPOGSPNSVCZQBSTFDPNNBOE
    3VCP$PQJTEFQFOEFOUPO1BSTFSHFN

    View full-size slide

  91. "CTUSBDU4ZOUBY5SFF
    % ruby_ast_visualizer -e 'include M’
    (send nil :include
    (const nil :M))
    Wrote a.png
    IUUQTHJUIVCDPNLPJDSVCZ@BTU@WJTVBMJ[FS

    View full-size slide

  92. EFG@OPEF@NBUDIFS
    def_node_matcher :include_statement, <<-PATTERN
    (send nil? ${:include :extend :prepend}
    (const nil? _))
    PATTERN
    3FXSJUFBTOPEFQBUUFSOCBTFEPO4FYQSFTTJPO
    'VSUIFSSFBEJOH
    IUUQTHJUIVCDPNSVCPDPQIRSVCPDPQCMPCNBTUFSMJCSVCPDPQOPEF@QBUUFSOSC

    View full-size slide

  93. 3VCP$PQ/PEF1BUUFSO
    (send nil? :include (const nil? _))
    (send nil? :extend (const nil? _))
    (send nil? :prepend (const nil? _))
    (send nil? ${:include :extend :prepend}
    (const nil? _))
    6TFA\AA^A NBUDIFTJODMVEF FYUFOEPSQSFQFOE
    "OEAA BSCJUSBSZNBUDIJOHDBOCFQFSGPSNFEPOB
    DBQUVSF
    'VSUIFSSFBEJOH
    IUUQTHJUIVCDPNSVCPDPQIRSVCPDPQCMPCNBTUFSMJCSVCPDPQOPEF@QBUUFSOSC

    View full-size slide

  94. PO@YYYBEE@PGGFOTF
    MSG = '`%s` is used at the top level.' \
    'Use inside `class` or `module`.'.freeze
    def_node_matcher :include_statement, <<-PATTERN
    (send nil? ${:include :extend :prepend}
    (const nil? _))
    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 8SJUFFWFOUIBOEMFSAPO@OPEF@OBNFA
    PSAJOWFTUJHBUFA
    NFUIPE

    View full-size slide

  95. *NQMFNFOUBUJPO
    3FE (SFFO 3FGBDUPS
    5FTUDPEFJTNPSFPCWJPVTBOEFBTJFSUP
    VOEFSTUBOEUIBOUIFPQFSBUJPOPG"45

    View full-size slide

  96. 8SJUFDPOpHpMFT
    Rails/TopLevelInclude:
    Description: 'Checks that `include`, `extend` and
    `prepend` exists at the top level.'
    Enabled: true
    # In this PR, the following setting has been
    removed
    Rails/TopLevelInclude:
    Include:
    - app/**/*.rb
    "EEBOFOUSZJOUPDPOpHFOBCMFEZNM
    PSDPOpHEJTBCMFEZNM

    "EEBOFOUSZJOUPDPOpHEFGBVMUZNM
    *GEFGBVMUTFUUJOHJTSFRVJSFE

    View full-size slide

  97. SBLFHFOFSBUF@DPQT@EPDVNFOUBUJPO
    % # Write the CHANGELOG.md
    % be rake generate_cops_documentation
    % be rake
    # be rake parallel:spec
    Finished in 39.07 seconds (files took 5.91 seconds
    to load)
    17739 examples, 0 failures, 1 pending
    # be rake parallel:ascii_spec
    Finished in 37.04 seconds (files took 5.26 seconds
    to load)
    17739 examples, 0 failures, 1 pending
    # be rake internal_investigation
    1046 files inspected, no offenses detected
    8IFOpOJTIFE SVO`rake
    generate_cops_documentation`UPVQEBUFUIFEPDT

    View full-size slide

  98. $POWFSTBUJPO

    View full-size slide

  99. $POWFSTBUJPO

    View full-size slide

  100. $POWFSTBUJPO

    View full-size slide

  101. $POWFSTBUJPO

    View full-size slide

  102. %JEZPVOPUJDFJU
    !QPDLF

    View full-size slide

  103. $POWFSTBUJPO

    View full-size slide

  104. SVCPDPQIRSVCPDPQ
    "EEOFXA4UZMF.JYJO6TBHFADPQ

    View full-size slide

  105. 3VCP$PQIBTOPQSFSFMFBTF

    View full-size slide

  106. w'BMTFQPTJUJWFʜ(PPE
    DPEF CVUPGGFOTF
    IBQQFOT
    w'BMTFOFHBUJWFʜ#BE
    DPEF CVUPGGFOTFEPFT
    OPUIBQQFO
    3FUSPTQFDUJWFUFSNT

    View full-size slide

  107. 3FUSPTQFDUJWFUFSNT
    QPTJUJWF OFHBUJWF

    USVF
 *UJTEFUFDUFEDPSSFDUMZ *UJTOPUEFUFDUFEDPSSFDUMZ

    GBMTF
 *UJTEFUFDUFEJODPSSFDUMZ *UJTOPUEFUFDUFEJODPSSFDUMZ

    View full-size slide

  108. GBMTFQPTJUJWF

    View full-size slide

  109. GBMTFQPTJUJWF

    View full-size slide

  110. GBMTFQPTJUJWF

    View full-size slide

  111. GBMTFQPTJUJWF

    View full-size slide

  112. GBMTFQPTJUJWF

    View full-size slide

  113. GBMTFQPTJUJWF

    View full-size slide

  114. *ODMVEFNBUDIFS

    View full-size slide

  115. 1SPQPTFlGBMTFOFHBUJWFz

    View full-size slide

  116. 1SPQPTFlGBMTFOFHBUJWFz

    View full-size slide

  117. 1SPQPTFlGBMTFOFHBUJWFz

    View full-size slide

  118. GBMTFQPTJUJWF
    ˣ
    GBMTFOFHBUJWF

    View full-size slide

  119. GBMTFQPTJUJWF

    View full-size slide

  120. FYQFDU@OP@PGGFOTFT

    View full-size slide

  121. FYQFDU@PGGFOTF

    View full-size slide

  122. 3FTPMWFEDPEF

    View full-size slide

  123. # In this PR, the following setting has been
    removed
    Rails/TopLevelInclude:
    Include:
    - app/**/*.rb
    $BVTFPGUIFQSPCMFN
    "EEBOFOUSZJOUPDPOpHEFGBVMUZNM
    *GEFGBVMUTFUUJOHJTSFRVJSFE

    *FYQBOEFEUIFTDPQFGSPN3BJMT
    UP4UZMFCVUUIFJNQMFNFOUBUJPO
    SFNBJOFEOBSSPX

    View full-size slide

  124. $VSSFOUMZUIFSFBSFOPGBMTFQPTJUJWFT

    View full-size slide

  125. w3FEVDFGBMTFQPTJUJWFTCZ
    SVOOJOHJO()SBJMTSBJMTSFQP
    w"OE3VOJOMPDBM3BJMTBQQ
    SFQP
    w*UNBZCFHPPEUPHPXJUI
    ()EJTDPVSTFEJTDPVSTF
    "DUJPOGSPN3FUSPTQFDUJWF

    View full-size slide

  126. "HFOEB
    0OUIFEJGGFSFODF
    CFUXFFODPEJOHTUZMFBOE
    -JOU &NVMBUF3VCZ`TXBSOJOH

    /FXDPQTUBSUTXJUI

    ZPVSQSPKFDU
    $SPTTPWFS

    044DPNNVOJUJFT
    1BSU
    1BSU
    1BSU

    View full-size slide

  127. $SPTTPWFS
    044
    DPNNVOJUJFT

    View full-size slide

  128. "TUPSZBCPVU
    JNQPSUDVTUPNDPQ
    GSPN3BJMTUP3VCP$PQ
    VQTUSFBN
    ()SVCPDPQIRSVCPDPQ
    ()SBJMTSBJMT

    View full-size slide

  129. SVCPDPQZNMBUSBJMTSBJMT

    View full-size slide

  130. SVCPDPQZNMBUSBJMTSBJMT
    %JTBCMFE#Z%FGBVMUUSVF

    View full-size slide

  131. SBJMTSBJMT
    "EEDVTUPN3VCP$PQGPSABTTFSU@OPUAPWFSASFGVUFA

    View full-size slide

  132. 3BJMTDPNNJUUFST
    TVHHFTUFEUPNF
    !ZZBHJ !LBNJQP

    View full-size slide

  133. #FOFpUTPG3BJMT
    VQTUSFBN
    ()SVCPDPQIRSVCPDPQ
    ()SBJMTSBJMT
    w3FEVDFEFQFOEFODZPO3BJMT
    w5IJTDVTUPNDPQNBZCF
    VTFEFOEVTFST

    View full-size slide

  134. #FOFpUTPGFOEVTFST
    VQTUSFBN
    ()SVCPDPQIRSVCPDPQ
    :PVSQSPKFDU
    ()SBJMTSBJMT
    w3FEVDFEFQFOEFODZPO3BJMT
    w5IJTDVTUPNDPQNBZCF
    VTFEBMTPCZFOEVTFST

    View full-size slide

  135. w(FNJGZUPOFX
    3VCP$PQ.5HFN
    wABTTFSU@OPUANFUIPEJT
    B"45FTU$BTFNFUIPE
    *UJTO`UB.5NFUIPE
    8IFSFUPFYQPSU
    SEQBSUZHFNT

    View full-size slide

  136. w(FNJGZUPOFX
    3VCP$PQ.5HFN
    wABTTFSU@OPUANFUIPEJT
    B"45FTU$BTFNFUIPE
    *UJTO`UB.5NFUIPE
    8IFSFUPFYQPSU

    View full-size slide

  137. "45FTU$BTF.55FTU
    IUUQTHJUIVCDPNSBJMTSBJMTCMPCWBDUJWFTVQQPSUMJCBDUJWF@TVQQPSUUFTU@DBTFSC--

    View full-size slide

  138. w4P &YQPSUUIJTDPQ
    UP3BJMTEFQBSUNFOU
    JO3VCP$PQ
    8IFSFUPFYQPSU

    View full-size slide

  139. SVCPDPQIRSVCPDPQ
    "EEOFXA3BJMT3FGVUF.FUIPETADPQ

    View full-size slide

  140. SVCPDPQIRSVCPDPQ
    SBJMTSBJMT

    View full-size slide

  141. TVQFS
    3VCP$PQ$PQ
    $VTUPN$PQT
    3FGVUF/PU
    PSJHJOBM
    DPQDMBTT
    1MVHHBCMFBSDIJUFDUVSF

    View full-size slide

  142. TVQFS
    3VCP$PQ$PQ
    $VTUPN$PQT
    3FGVUF/PU
    3BJMT3FGVUF.FUIPET
    .PTUMZUIFJNQMFNFOUBUJPOXBTJOUBDU
    PSJHJOBM
    DPQDMBTT
    JNQPSUFE
    DPQDMBTT
    1MVHHBCMFBSDIJUFDUVSF

    View full-size slide

  143. w3BJMTDPNNVOJUZ
    DPOUSJCVUPSDPNFUP
    3VCP$PQDPNNVOJUZ
    "OJOUFSFTUJOHQIFOPNFOPO

    View full-size slide

  144. $PNNFOUFECZ"3BJMTDPOUSJCVUPS

    View full-size slide

  145. *NQPSUFEBOPUIFSDPQGSPN3BJMT

    View full-size slide

  146. 3VCP$PQ
    JT

    SFMFBTFE
    3VCP$PQ
    JT

    FOBCMFEXJUI$PEF$MJNBUF
    *OUIFGVUVSFXPSME
    *GUIFGPMMPXJOHDPOEJUJPOT
    BSFNFU 3BJMTDBOMFBWF
    UIFTFDPQTUP3VCP$PQ

    View full-size slide

  147. #FUUFS
    MFBWFJUUP
    FYQFSUT

    View full-size slide

  148. #FOFpUTPGFOEVTFSTBOE
    VQTUSFBN
    ()SVCPDPQIRSVCPDPQ
    :PVSQSPKFDU
    (SFBUSFQPT
    ZPVLOPX
    w3FEVDFEFQFOEFODZPOFYQPSUFESFQP
    w5IJTDVTUPNDPQNBZCFVTFEFOE
    VTFST
    w$PNNVOJUZQFPQMFBSFDPOOFDUFE

    View full-size slide

  149. "HFOEB
    0OUIFEJGGFSFODF
    CFUXFFODPEJOHTUZMFBOE
    -JOU &NVMBUF3VCZ`TXBSOJOH

    /FXDPQTUBSUTXJUI

    ZPVSQSPKFDU
    $SPTTPWFS

    044DPNNVOJUJFT
    1BSU
    1BSU
    1BSU

    View full-size slide

  150. 5PEBZ`TTUPSZXBT
    BHSFBUQSFTFOUBUJPO
    BGUFSZFBSTGSPN
    IUUQKQSVCZJTUOFU3VCZ,BJHJ-PH4IUNM

    View full-size slide

  151. w7BSJPVTDPNQBOJFTVTJOH3VCZ
    3BJMTGPSEFWFMPQNFOUBQQFBSFE
    w(JU)VCIBTBQQFBSFE BOE
    JOEJWJEVBMBDUJWJUJFTBSFESBXJOH
    BUUFOUJPO
    w3VCZJTUTBOE3VCZJTIDPNQBOJFT
    NBLFTWBSJPVT3VCZDPEJOHTUZMFT
    .PEFSOUJNFT

    View full-size slide

  152. .PEFSOUJNFT
    VQTUSFBN
    ()SVCPDPQIRSVCPDPQ
    3VCZ
    :PVSQSPKFDU
    ()SBJMTSBJMT
    w3VCZVTFEJOWBSJPVTQMBDFT
    w7BSJPVTJNQPSUTPVSDFT

    View full-size slide

  153. .PEFSOUJNFT
    VQTUSFBN
    ()SVCPDPQIRSVCPDPQ
    3VCZ
    :PVSQSPKFDU
    ()SBJMTSBJMT
    w5IFSFJTBQPTTJCJMJUZUIBU$PQ
    UIBUJTVTFGVMUPPUIFSTDBOCF
    VTFGVMGPSPUIFST

    View full-size slide

  154. .PEFSOUJNFT
    VQTUSFBN
    ()SVCPDPQIRSVCPDPQ
    3VCZ
    :PVSQSPKFDU
    ()SBJMTSBJMT
    w%JWFSTJUZZPVDBODIBOHFBOE
    DVTUPNJ[FJUGPSZPVSQSPKFDU
    EFGBVMU
    PS
    DVTUPN

    View full-size slide

  155. w'JSTUPGBMM ZPVDBOVTFJUBT
    EFGBVMUPSDVTUPNJ[FJU
    w:PVDBOPQFOB13UPVQTUSFBN
    BOZUJNF
    w5IFSFBSFWBSJPVTTUBSUJOHNFUIPET
    w6TFUIFPQQPSUVOJUZUPMJTUFOUP
    QFPQMFZPVLOPX
    %FGBVMUTUZMFJTO`UUIFPOMZTFUUJOH

    View full-size slide

  156. IUUQBHJMFNBOJGFTUPPSH

    View full-size slide

  157. IUUQBHJMFNBOJGFTUPPSH

    View full-size slide

  158. 4P :PVBMSFBEZ
    IBWF
    PQQPSUVOJUJFT

    View full-size slide

  159. One more thing…

    View full-size slide

  160. 3BJMT0441BUDINFFUVQ

    View full-size slide

  161. 4PDJBMDPEJOHTUBSUTXJUIZPV
    :PV

    View full-size slide

  162. !LPJD
    5IBOLT .*/"48"/

    View full-size slide

  163. l
    "QSPCMFNJTpYFE
    OPUCFDBVTFUIFSFBSF
    QFPQMFJOUSPVCMF
    CVUCFDBVTFUIFSFBSF
    QFPQMFXIPXBOUUPpYJU
    ࠔ͍ͬͯΔਓ͕͍Δ໰୊͕௚ΔͷͰ͸ͳ͘ɺ
    ௚͢ؾͷ͋Δਓ͕͍Δ໰୊͕௚ΔCZ!LBNJQP

    View full-size slide