Slide 1

Slide 1 text

େࡕ3VCZձٞ ౔ த೭ౡϑΣεςΟόϧλϫʔɾ΢Σετ ,PJDIJ*50&4. *OD .JOJGZ3VCZ$PEF Ruby Code Golf with Practical Code

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

3VCZηϛφʔ౦ژ ೥݄೔ ۚ σϑΥϧτʹ͍ۙઃఆͰ͔͑ͬͯಡΈʹ͍͘मਖ਼Λ͍ͯ͠Δํ΁ͷώϯτΛ

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

Support OSS community

Slide 6

Slide 6 text

w !LPJD1BSTFSHFNίϛολʔ w !KVOL-SBNBίϛολʔ w !4)(".&-*/,4QBSTFZίϯτϦϏϡʔλ w !GVHBLLCO3#4ίϯτϦϏϡʔλ w ෦һืूதʂ ߏจղੳثݚڀ෦ IUUQTNBHB[JOFSVCZJTUOFUBSUJDMFT'PMMPX6Q,JSJTIJNB3VCZIUNM

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

.JOJGZ3VCZ$PEF ڝٕϓϩάϥϛϯάͰΈΔ 3VCZͷ๛͔͞ ʮಈ࡞͢Δ͖Ε͍Ͱ͸ͳ͍ίʔυʯͷ࿩ ࢓ࣄͰ͸ͦΜͳ໨ඪΛܝ͛·ͤΜͷͰ҆͝৺͍ͩ͘͞ dLPJD dIBSVHVDIJ

Slide 9

Slide 9 text

ʰ-3Ͱ+40/ύʔαʔΛ࡞Δʱ w dKVOL 1SFNJVN4QPOTPS w dIBSVHVDIJ w dLPJD "TLUIF4QFBLFST ग़ுʂߏจղੳثݚڀ෦ 4QPOTPS-5 ݚᮎ3VCZϓϩάϥϛϯά ٳܜ࣌ؒʹϒʔε ͰखചΓ͞Ε·͢ Կ࡭Ͱ΋ങ͓͏ʂ

Slide 10

Slide 10 text

ࠓ೔ͷ࿩

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

w ൃද࣌ͷ࠷৽ͷ3VCZͰ͋ΔEFWͱɺ 1SJTNͷ࣍ͷ։ൃ൛Λલఏʹͯ͠·͢ ຊτʔΫʹ͓͚Δόʔδϣϯ $ ruby -rprism -ve 'p Prism::VERSION' ruby 3.4.0dev (2024-07-30T06:31:58Z master 1870505f47) [x86_64-darwin23] "0.30.0" # ݫີʹ͸0.31.0޲͚ͷ։ൃ൛ rbenv install 3.4-devͳͲͰ͓खݩʹΠϯετʔϧ

Slide 13

Slide 13 text

.JOJGZͷݱ࣮ͱՄೳੑ 1SJTN"1*ͱ-FYFS .JOJGZ3VCZ$PEF ໨࣍

Slide 14

Slide 14 text

.JOJGZͷݱ࣮ͱՄೳੑ

Slide 15

Slide 15 text

w ιʔείʔυͷαΠζΛখ͘͢͞Δ w 8FCͷੈքͰ͸ɺ)5.- +BWB4DSJQU $44 ͳͲϦιʔεͷωοτϫʔΫసૹྔΛݮΒ͢ w ϓϩάϥϛϯάݴޠͷ.JOJGZπʔϧͱͯ͠ɺ ྫ͑͹+BWB4DSJQUͰ͸6HJMJGZ+4 5FSTFSͳͲ .JOJGZͱ͸ʁ

Slide 16

Slide 16 text

+BWB4DSJQUઌഐͰͷ.JOJGZྫ function greet(name) { console.log(`Hello! ${name}`); } greet("Osaka RubyKaigi 04"); // Hello, Osaka RubyKaigi 04! HSFFUKT $ npx terser greet.js function greet(name){console.log(`Hello! ${name}`)}\ greet("Osaka RubyKaigi 04"); .JOJGZ͢Δ εϖʔεͷ౎߹ʹ͖࣮ͭࡍ͸ߦ

Slide 17

Slide 17 text

w ಈ࡞͢ΔͨΊʹඞཁͷͳ͍εϖʔεɺվߦɺ ίϝϯτɺηϛίϩϯͷྨΛআڈ͢Δ w ϨΠΞ΢τ΍ߦؒΛ่͠ɺݟͨ໨Λ6HMJGZ͢Δ w ʮಈ࡞͢Δ͖Ε͍ͳίʔυʯͱҟͳΔՁ஋؍ ಈ࡞͢Δ୹͍ίʔυ $ npx terser greet.js | tee >(node) function greet(name){console.log(`Hello! ${name}`)} greet("Osaka RubyKaigi 04"); Hello! Osaka RubyKaigi 04 UFSTFSͷ݁ՌΛϓϩηεஔ׵Ͱ࣮ߦͨ݁͠Ռ

Slide 18

Slide 18 text

w ಉ͡ৼΔ෣͍ͳΒ୹͍ํ͕ྑ͍ w ܭࢉػʹͱͬͯίʔυՄಡੑ͸ॏཁͰͳ͘ɺ ωοτϫʔΫసૹΛқ͘͢͠Δͷ͕࣮ફత w લड़ͷαϯϓϧίʔυͰ͸ʹѹॖ͞ΕΔ .JOJGZͷՁ஋؍ $ wc -c greet.js 120 greet.js $ npx terser greet.js | wc -c 80

Slide 19

Slide 19 text

w $PNQSFTT͸ɺෆཁͳεϖʔε΍ίϝϯτͷ ࡟আ΍ɺߏจͷ୹ॖԽʹΑͬͯɺϓϩάϥϜ ͷ͍ͨΔՕॴΛ୹͘͢Δ ຊฤ͸͜ͷҰ෦ w .BOHMF͸ม਺໊΍ؔ਺໊Λ୹ॖ͢Δ w ಉ͡ৼΔ෣͍ͷ··ʮѹྗʯ͕ΑΓ ߴ͍ํ͕ɺΑΓՁ஋͋Δ୹͍ίʔυ $PNQSFTTͱ.BOHMF

Slide 20

Slide 20 text

ͦ΋ͦ΋ͳͥ .JOJGZ

Slide 21

Slide 21 text

w 3BJMTΞϓϦέʔγϣϯͷσϓϩΠΛಛఆͷ αʔόʔʹߦͳ͍ɺͦ͜ʹରͯ͠ϦΫΤετ ͕ूத͢Δݱ୅Ͱ͸ແԑ w ΋͠.JOJGZࡁΈίʔυ͕σϓϩΠ͞ΕΔͱɺ ໰୊͕ى͖ͨͱ͖ߦ൪߸͕ࢦ͔͢Β໰୊Օॴ ͷಛఆ͕ࠔ೉ʹͳͬͯࠔΔ ͦΕ͸ͦ͏ ݱ୅ͷ͓࢓ࣄ3VCZͩͱͲ͏ʁ

Slide 22

Slide 22 text

w ໝ૝ͦͷɻSVCZXBTNͷίʔυͰ֎෦Ϧιʔ εΛཁٻͨ͠ࡍʹɺ*4FRͳͲͷதؒදݱͰͳ͍ QMBJOͳ3VCZίʔυͷωοτϫʔΫసૹྔݮʁ w ໝ૝ͦͷɻΤοδίϯϐϡʔςΟϯάͰɺΤο δαʔόʔ $%/ ΍ΤοδσόΠε *P5 ΁ͷ ίϯςϯπ΍σʔλͷ഑෍ʹ͓͍ͯ༗༻ʁ ະདྷͷ͓࢓ࣄ3VCZͩͱͲ͏ʁ NJOJGZ͸1JDP3VCZͷϝϞϦ࡟ݮʹ࢖͑Δ͸ͣͳͷͰ஫໨͍ͯ͠·͢ɻ IUUQTYDPNIBTVNJLJOTUBUVT

Slide 23

Slide 23 text

w དྷ೥3VCZ,BJHJ দࢁ Ͱ53*$, ͕։࠵͞ΕΔΒ͍͠Ͱ͢Αʁ w ࢓ࣄ΍044Ͱ໨ࢦ͍ͯ͠Δʮಈ࡞͢Δ͖Ε͍ ͳίʔυʯͰ͸ͳ͍෯Λ࡞ΔػձॏཁͰ͸ʁ w .JOJGZ͢Δͷʹ͸ʮιʔείʔυͷղੳʯ͕ ඞཁͰͦΕ͸͢ͳΘͪɺ͍·ྲྀߦΓͷʂʁ དྷ೥ͷ3VCZΠϕϯτͩͱͲ͏ʁ

Slide 24

Slide 24 text

ߏจղੳث .BU[͸ݴ͍·ͨ͠ύʔαʔͱ($ͱίʔυδΣωϨʔλʹ͸ۙͮ͘ͳ

Slide 25

Slide 25 text

1SJTN"1*Ͱιʔεղੳ

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

w τʔΫϯྻ͸ιʔείʔυΛࠨ͔ΒӈʹಡΜͩ τʔΫϯͷ഑ྻ w ߏจ໦͸ϓϩάϥϜͷߏจߏ଄Λϊʔυͱͯ͠ πϦʔߏ଄Ͱදݱ͍ͯ͠Δ w ྫ͑͹ΫϥεఆٛͷϊʔυͷԼʹϝιουఆٛͷ ϊʔυ͕͋ΔͳͲߏจ໦ͷํ͕๛͔ͳσʔλߏ଄ τʔΫϯྻͱߏจ໦

Slide 28

Slide 28 text

w γϯϘϧΛҾ਺ʹͨ͠ϝιουݺͼग़͠ τʔΫϯྻͷαϯϓϧ puts :hello [:IDENTIFIER, :SYMBOL_BEGIN, :IDENTIFIER, :EOF] puts : hello %w(foo) [:PERCENT_LOWER_W, :STRING_CONTENT, :STRING_END, :EOF] w ཁૉͻͱͭͷXϦςϥϧ %w( foo )

Slide 29

Slide 29 text

ߏจ໦ͷαϯϓϧ $ ruby -rprism -e 'p Prism.parse("42").value' @ ProgramNode (location: (1,0)-(1,2)) ├── flags: ∅ ├── locals: [] └── statements: @ StatementsNode (location: (1,0)-(1,2)) ├── flags: ∅ └── body: (length: 1) └── @ IntegerNode (location: (1,0)-(1,2)) ├── flags: newline, static_literal, decimal └── value: 42 Prism.parseͰPrism::ParseResultΛಘΔ

Slide 30

Slide 30 text

ߏจ໦ ࠓճׂѪ ࠓ೔͖ͬͱۚࢠ͞Μ͕୔ࢁ࿩͍ͯ͠Δʂ

Slide 31

Slide 31 text

w 3VCP$PQͷΑ͏ʹߏจͷैଐؔ܎Λ૸ࠪ͠ ͯɺΦʔτίϨΫτͰߏจॻ͖׵͍͑ͨ͠Α ͏ͳέʔε͸ߏจ໦Λѻ͑ͳ͍ͱ೉͍͠ w ࠓճͷ.JOJGZ࿩Ͱ͸جຊతʹߏจΛॻ͖׵͑ ͳ͍ͷͰɺτʔΫϯྻͰे෼ͱ͍͏൑அ τʔΫϯྻͱߏจ໦ͷ࢖͍෼͚ ͬ͘͟Γ͍͏ͱߏจߏ଄΁ͷॲཧ͢ΔͱͳͬͨΒߏจ໦͕ཉ͘͠ͳΔ

Slide 32

Slide 32 text

ࠓճ͸τʔΫϯྻ

Slide 33

Slide 33 text

w Ripper.lexͱPrism.lex͍ͣΕ΋ϓϩάϥϜ ͷτʔΫϯྻΛखʹೖΕΔ͜ͱ͕Ͱ͖Δ"1* w ͔ͤͬ͘ͳͷͰɺ·ͩ৘ใ͕গͳ͍1SJTNΛ࢖ͬ ͯΈͨํ͕͓΋͠Ζͦ͏ ϓϩϙʔβϧతʹ΋ w Prism.lex_ripperͱPrism.lex_compat͸ 3JQQFSʹ͍ۙ"1*͕ͩɺࠓճૉ௚ʹPrism.lex 3VCZͷτʔΫϯऔಘ"1*બఆ

Slide 34

Slide 34 text

1SJTNMFYͷجຊ"1*

Slide 35

Slide 35 text

w Prism.lexϝιουͰղੳ݁ՌΛද͢ Prism::LexResultΦϒδΣΫτΛಘΒΕΔ w 📝1SJTN·ͰPrism::ParseLexResult Λޡͬͯฦͯ͠Δ ৄ͘͠͸SVCZQSJTN 1SJTNMFY require 'prism' result = Prism.lex('puts :hello') result.class #=> Prism::LexResult

Slide 36

Slide 36 text

w LexResult.valueͰτʔΫϯΛද͢ Prism::TokenͱMFYTUBUF CJU஋ ͷ഑ྻ֫ಘ w MFYTUBUF஋͸Լهࢀর ຊฤະ࢖༻ʹׂ͖ͭѪ 1SJTN-FY3FTVMU require 'prism' result = Prism.lex('puts :hello') result.value.class #=> Array result.value.first #=> [#, 32] IUUQTHJUIVCDPNSVCZQSJTNCMPCWJODMVEFQSJTNQBSTFSI--

Slide 37

Slide 37 text

w LexResult.valueͷ഑ྻͷୈҰཁૉ Prism::Token͸ܕɺ஋ɺҐஔ৘ใΛ࣋ͭ 1SJTN5PLFO result = Prism.lex('puts :hello') token, _state = result.value.first token.class #=> Prism::Token token.type #=> :IDENTIFIER token.value #=> "puts" token.location.class #=> Prism::Location

Slide 38

Slide 38 text

w ParseToken.locationͰτʔΫϯͷҐஔ ৘ใΛ࣋ͭPrism::LocationΛಘΒΕΔ 1SJTN-PDBUJPO result = Prism.lex('puts :hello') token, _state = result.value.first location = token.location location.first_line #=> 1 location.start_offset #=> 0 location.length #=> 4

Slide 39

Slide 39 text

τʔΫϯॲཧͷఆੴαϯϓϧ tokens = Prism.lex(source).value tokens.each_cons(2)do|(token,_),(next_token,_)| case token.type when :COMMENT # do_something when :IDENTIFIER # do_something end prev_token = token end FBDI@DPOT Ͱ࣍ͷτʔΫϯ৘ใΛઌಡΈ͢Δ QSFW@UPLFOͰલͷτʔΫϯ৘ใΛอ͓࣋ͯ͘͠ ͜ͷ͋ͱ঺հ͢Δ.JOJGZ3VCZ͸͜ͷͭ͘Γ UPLFOUZQFͷछྨͰॲཧΛ൑ผ͢Δ ࠨ͔Βӈ΁ͷτʔΫϯྻͷϧʔϓ

Slide 40

Slide 40 text

ࣈ۟ղੳͱߏจղੳͷར༻ྫ ࣈ۟ղੳ ߏจղੳ ѹॖॲཧ ѹॖ͞Εͨίʔυ ιʔείʔυ ೖྗ ॲཧ ग़ྗ

Slide 41

Slide 41 text

.JOJGZ3VCZ$PEF

Slide 42

Slide 42 text

github.com/koic/minifyrb

Slide 43

Slide 43 text

w minifyrbίϚϯυͰɺෆཁͳίʔυ෦෼ɺ ͭ·ΓτʔΫϯΛআڈͯ͠ίʔυΛѹॖ͢Δ .JOJGZ3VCZHFN $ gem i minifyrb $ echo "puts :hello" | minifyrb puts:hello

Slide 44

Slide 44 text

0SJHJOBM$PEF

Slide 45

Slide 45 text

.JOJ fi FE$PEF

Slide 46

Slide 46 text

ઃܭํ਑

Slide 47

Slide 47 text

w ͳͯ͘΋ྑ͍ۭന΍վߦΛۃྗআڈ͢Δ w ίϝϯτΛআڈ͢Δ w ඞཁʹԠͯ͡ηϛίϩϯʹΑΔϫϯϥΠφʔ w ม਺໊΍ϝιου໊Λ୹ॖ͢Δ.BOHMF͸ ෳࡶʹͳΔͨΊߦΘͳ͍ ࠓޙͷల๬࿮ ݱ࣌఺ͷجຊతͳߟ͑ํ

Slide 48

Slide 48 text

w {}ϕʔεͷߏจͱͳΔ+BWB4DSJQUͰ͸ྫ͑͹ functionΛҰߦͰෳ਺ఆٛͰ͖Δ +BWB4DSJQUͷϫϯϥΠφʔʹֶͿ $ cat example.js | tee >(npx terser) function foo() { console.log(bar()); } function bar() { 42; } function foo(){console.log(bar())}function bar(){42} εϖʔεɺηϛίϩϯෆཁ ಡΈ΍͢͞ͷվߦΛ͢Δ

Slide 49

Slide 49 text

w FOEϕʔεͷߏจͱͳΔ3VCZͰ͸ྫ͑͹վߦ Ληϛίϩϯʹஔ͖׵͑ͯ΋ɺ݁ہόΠτ ͷαΠζֻ͕͔Δ͜ͱ͸มΘΒͳ͍ w FOE͸^ͱൺ΂ɺ۠੾Γεϖʔε͕ඞཁ͔൑அ w ౰ॳ͸σόοά࣌ͷߦ൪߸Λ஌ΔҙຯͰ΋ɺ ෳ਺ߦͷ··Ͱྑ͍ͱ͍͏τϨʔυΦϑ൑அ 3VCZͷϫϯϥΠφʔ ِ 1όΠτ

Slide 50

Slide 50 text

w FOEϕʔεͷߏจͱͳΔ3VCZͰ͸ྫ͑͹վߦ Ληϛίϩϯʹஔ͖׵͑Δͱɺ8JOEPXTͳΜ ͔ͷaSaOͷόΠτվߦ͸όΠτʹݮΒͤΔ w .JOJGZͱ͍͏ํ਑ʹ͓͚ΔτϨʔυΦϑ൑அ͸ ໰୊௥੻ੑΑΓ΋୹͍ίʔυΛऔΔ w ݁Ռͱͯ͠෭࡞༻ʹएׯͷ೉ಡԽ͕͍͖ͭͯͨ 3VCZͷϫϯϥΠφʔ ਅ

Slide 51

Slide 51 text

Prism.lex͸&SSPS5PMFSBODFʹͳͬͯΔ &SSPS5PMFSBODF $ ruby -ce 'cond(arg)?x:y' # εϖʔεͳ͠ѹॖ͸ߏจΤϥʔͷྫ -e:1: syntax error, unexpected symbol literal, expecting 'do' or '{' or '(' cond(arg)?x:y ruby: compile error (SyntaxError) $ ruby -ce 'cond(arg)?x: y' # ͜ͷ৔߹:ͱyͷؒʹཁεϖʔε Syntax OK $ ruby -rprism -e "p Prism.lex('cond(arg)?x:y').value" [[#

Slide 52

Slide 52 text

w .JOJGZ͸-41ͷΑ͏ͳೖྗ్தͷίʔυΛॲཧ ͢Δ΋ͷͰ͸ͳ͍ w ಈ͔ͳ͍ίʔυΛ.JOJGZͯ͠΋࢓ํͳ͍ͷͰɺ ݩίʔυ͕ߏจΤϥʔͷͱ͖͸Τϥʔͱͨ͠ w Prism.lex(code).errorsͷ݁Ռ഑ྻ΍ Prism.parse_success?Ͱ஌Δ͜ͱ͕Ͱ͖Δ &SSPS5PMFSBODF΁ͷ൑அ Prism::ParseLexResult#errors

Slide 53

Slide 53 text

τʔΫϯॲཧͷ࣮૷

Slide 54

Slide 54 text

w *(/03&%@/&8-*/&ଥ౰ͳγϯλοΫ εͰ͋ΔͨΊʹෆඞཁͳվߦ ୯ʹ࡟আՄೳ w /&8-*/&ଥ౰ͳγϯλοΫεͰ͋Δͨ Ίʹඞཁͳվߦ ୯ʹ࡟আ͢ΔͱߏจΤϥʔ छྨͷվߦτʔΫϯ ݱࡏͷ1SJTN ࣮૷ͩͱظ଴ͱҧ͏෦෼΋͋Γޙड़

Slide 55

Slide 55 text

w ͜ͷվߦ͕ͳ͘ͳͬͯ΋ߏจͱͯ͠ଥ౰Ͱ͋Δ w ηϛίϩϯͳ͠Ͱվߦ࡟আ͸Ͳ͜·ͰͰ͖Δʁ *(/03&%@/&8-*/&τʔΫϯ begin rescue CustomError=>e else ensure end ݩ͸όΠτ aOͷ৔߹ begin rescue CustomError=>e else ensure end *(/03&%@/&8-*/&ద༻ όΠτ begin rescue CustomError=>e;else ensure end ࢀߟผ్ηϛίϩϯஔ׵ όΠτ

Slide 56

Slide 56 text

w ʮಈ࡞͢Δ͖Ε͍Ͱ͸ͳ ͍ίʔυʯ͕ຊτʔΫͷ ςʔϚͰ͢Α w .JOJGZͱ53*$,೴͸ີ઀ ʹؔ࿈͢ΔԾઆ w 53*$,ͷLJOBCB͞ Μ࡞඼ͷཧղʹ͚ۙͮΔʁ ͜ͷτʔΫϯ͔ΒಘΒΕΔֶͼ IUUQTHJUIVCDPNUSJDUSJDLCMPCNBTUFSLJOBCBFOUSZSC 53*$,໊࡞ͷͻͱͭ

Slide 57

Slide 57 text

w "\r\n"͔΋͠Εͳ͍վߦΛ۠੾ΓτʔΫϯʹ ͢Δ͜ͱͰόΠτ਺ΛݮΒͤΔՄೳੑ͕͋Δ w *(/03&%@/&8-*/&ͱҧ͍ɺdef foo͕ deffooʹͳΒͳ͍Α͏దٓ۠੾Γௐ੔͕ඞཁ w ࣍τʔΫϯͷܕ͕&0'ͷ৔߹͸104*9४ڌͷ ςΩετϑΝΠϧͱ͢ΔͨΊվߦΛҡ࣋͢Δ /&8-*/&τʔΫϯ

Slide 58

Slide 58 text

104*9४ڌҧ൓👮 (JU)VCͷΞϨ /&8-*/& &0'

Slide 59

Slide 59 text

w BMJBTFRM ͕BMJBTFRM ͸ߏจΤϥʔ w GPP 'PP͕GPP 'PP͸ҙຯ͕มΘΔ w BSSBZ͕BSSBZ͸ߏจΤϥʔ w GPPX BCD ͕GPPX BCD ͸ҙຯ͕มΘΔ w GPPX BGPSC ͕GPPX BGPSC ͸ߏจΤϥʔ ݁߹ͯ͠͸͍͚ͳ͍γϦʔζͷҰ෦ unexpected char literal unexpected operator assignment unexpected ')'

Slide 60

Slide 60 text

w ด͡Χοίલͷվߦ͸IGNORED_NEWLINEʹͰ͖Δ ͸͕ͣͩɺΧϯϚͳͩ͠ͱNEWLINEͱ͞ΕΔ ҙਤతͳ3JQQFSޓ׵ɺSVCZQSJTNࢀর w ;΁ͷ୯७ͳஔ׵͸[foo, bar, baz;]ͷߏจΤϥʔ <ิ଍>୯७ͳηϛίϩϯஔ׵͸ෆՄ [ foo, bar, baz ] :BRACKET_LEFT_ARRAY,:IGNORED_NEWLINE :IDENTIFIER, :COMMA,:IGNORED_NEWLINE :IDENTIFIER, :COMMA,:IGNORED_NEWLINE :IDENTIFIER, :NEWLINE :BRACKET_RIGHT, :NEWLINE, :EOF

Slide 61

Slide 61 text

վߦͷτʔΫϯॲཧ֓ཁ tokens.each(2) do |(token, _), (next_token, _)| case token.type when :IGNORED_NEWLINE # noop when :NEWLINE token_value = if next_token.type == :EOF token.value elsif CLOSING_DELIMITER_TYPES.include?(next_token.type) # noop else ';' end 104*9ͷΞϨ΁ͷOFXMJOFରԠ Ճ͑ͯɺdeffooͳͲ༧໿ޠ͕݁߹͠ͳ͍Α͏ͳॲཧΛผ్͍ͯ͠Δ > ^ͷτʔΫϯͷఆ਺ɻຊདྷ*(/03&%@/&8-*/&͔΋ͳύον

Slide 62

Slide 62 text

w )&3&%0$@45"35ͱ)&3&%0$@&/%ͷ τʔΫϯʹғ·ΕͨτʔΫϯ͕ຊจ )&3&%0$@ 45"35c&/% τʔΫϯ <

Slide 63

Slide 63 text

w γϯϓϧͳώΞυΩϡϝϯτͳΒ )&3&%0$@45"35͔Β)&3&%0$@&/%· ͰͷτʔΫϯ஋Λ݁߹͢Ε͹ऴΘΓͦ͏ w τʔΫϯྻ͸ιʔείʔυΛࠨ͔ΒӈʹಡΜ ͩ݁Ռͷ഑ྻͱݴͬͨͳʁ ώΞυΩϡϝϯτ

Slide 64

Slide 64 text

w :DOT, :IDENTIFIER͸:HEREDOC_STARTʹ ଓ͘τʔΫϯͰ͸ͳ͍ w ώΞυΩϡϝϯτΛจࣈྻϦςϥϧͷҰछͩͱࢥ ͑͹"text".do_somethingͳͷͰͦΕ͸ͦ͏ )&3&%0$EP@TPNFUIJOH <

Slide 65

Slide 65 text

w ୹͍όΠτ਺ʹ͢Δํ਑ʹج͖ͮIFSFEPD͸ จࣈྻϦςϥϧʹஔ׵͢Δ͜ͱͱͨ͠ w )&3&%0$@45"35͔Β)&3&%0$@&/%· Ͱ͸ώΞυΩϡϝϯτͰ͋Γɺdͷ৔߹͸ IFSFEPDऴྃͰEFEFOU͢ΔΑ͏ঢ়ଶΛอͭ )&3&%0$EP@TPNFUIJOH <

Slide 66

Slide 66 text

IFSFEPDͷτʔΫϯॲཧ֓ཁ tokens.each(2) do |(token, _), (next_token, _)| case token.type when :HEREDOC_START @in_heredoc = true squiggly_heredoc = token.value.start_with?('<<~') # SNIP: <<'HEREDOC', <<"HEREDOC", <<`HEREDOC`΁ͷॲཧׂѪ when :HEREDOC_END heredoc_contents = @heredoc_content_tokens.join # SNIP: <<~΁ͷdedentॲཧΛׂѪ @minified_values << heredoc_contents @minified_values << (@string_quote == '`' ? '`' : '"') @heredoc_content_tokens.clear @in_heredoc = false IFSFEPDதͷτʔΫϯॲཧΛ༗ޮԽ IFSFEPDதͷτʔΫϯॲཧΛແޮԽ EFEFOUॲཧ͕ඞཁ͔ঢ়ଶΛ࣋ͨͤΔ IFSFEPD͸ແҹҎ֎ΫΥʔτ͕ͱ͓Γ IFSFEPDຊจͷτʔΫϯ஋ͷ഑ྻΛ݁߹

Slide 67

Slide 67 text

͢΂ͯΛ෺ޠΔλΠτϧɻࠓճͷHFN͸IFSFEPD͕ਖ਼௚·ͩόΪʔ IUUQTTQFBLFSEFDLDPNZVJ@LOLIFSFEPDJOEFNPODBTUMF

Slide 68

Slide 68 text

ࠓޙͷ֦ுʹ޲͚ͨ஫ҙ఺ def m(a) bar unless cond end def m(a)bar unless cond end w Ҿ਺Χοί͋Γͷɺվߦ΍ηϛίϩϯͳ͠Ͱॻ͚ΔFOE͋Γͷ ϫϯϥΠφʔϝιουఆٛʹ͍ͭͯߟ͑Δ ಉ͡ߏจ໦

Slide 69

Slide 69 text

FOEMFTTEFGͱ͸ߏจ͕ҟͳΔ w .BOHMJOHΛߟ͑Δ৔߹͸-FYFSτʔΫϯΑΓ ߏจ໦Ͱͷॲཧ͕޲͍͍ͯΔ͔΋ def foo(a)=bar unless cond def foo(a)bar unless cond end ҟͳΔߏจ໦

Slide 70

Slide 70 text

ެ։ ͜ΜͳࢥߟΛͭͭ͠Ͱ͖·ͨ͠

Slide 71

Slide 71 text

# Original $ find . -name '*.rb' -type f -print0 | \ xargs -0 wc -c | awk 'END{print $1}' 49825 # Original $ find . -name '*.rb' -type f -print0 | \ xargs -0 wc -c | awk 'END{print $1}' 49825 # Minify $ bundle exec rake minify $ find . -name '*.rb' -type f -print0 | \ xargs -0 wc -c | awk 'END{print $1}' 31598 # Original $ find . -name '*.rb' -type f -print0 | \ xargs -0 wc -c | awk 'END{print $1}' 49825 # Minify $ bundle exec rake minify $ find . -name '*.rb' -type f -print0 | \ xargs -0 wc -c | awk 'END{print $1}' 31598 # Ratio $ ruby -e 'p 31598 / 49825.0' 0.6341796287004515 .JOJGZͰͲΕ͘Β͍ݮΔʁ

Slide 72

Slide 72 text

w MJC͸ όΠτ͔Β όΠτʹͳΓɺ TQFD͸ όΠτ͔Β όΠτʹ ͳΔ w ͭ·Γ࡟ݮ͞Εͨίʔυ͸34QFDͷํ͕ߴ͍ w ࣮ફత ͱ͸ʁ ʹ͸ϓϩμΫτίʔυ΁ͷޮ Ռ͕ߴ͍ํ͕͍͍Μ͚ͩͲݱ࣮͸͜͏Β͍͠ ଌఆͱධՁΛ΋͏গ͠

Slide 73

Slide 73 text

github.com/koic/minifyrb gem install minifyrbͰ༡ΜͰΈͯͶ

Slide 74

Slide 74 text

͓΅͍͑ͯ·͔͢ʁ

Slide 75

Slide 75 text

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

Slide 76

Slide 76 text

One More Thing

Slide 77

Slide 77 text

" ࠞಱͱடং

Slide 78

Slide 78 text

.JOJGZͨ͠ίʔυͱ ΋ͬͱٔΕΔ

Slide 79

Slide 79 text

w ೉ಡԽʹର͢Δ෮߸ԽΈ͍ͨͳ΋ͷ w ͓࢓ࣄʹݶΒͣɺ;ͩΜ͸ΈΜͳߦّͷྑ͍ ίʔυΛແҙࣝʹ໨ࢦͯ͠͠·͍·͢ΑͶʁ w 3VCP$PQͷΦʔτίϨΫτͱ͍͏ ϑΥʔϚολʔͷྗͷ࠶ൃݟ .JOJGZͰյͯ͠3VCP$PQͰ௚͢ .JOJGZͨ͠ίʔυ͕Ͳ͏෮ݩͰ͖Δ͔ڵຯΛ࣋ͪ·͢ΑͶʁ

Slide 80

Slide 80 text

w .JOJGZͱ3VCP$PQͱ͍͏ࠞಱ͔Βͷ૑଄ w 3VCP$PQͷΤοδέʔεॲཧʹ͍ͭͯɺ NJOJGZͨ͠ίʔυΛݩʹ͢Ε͹؆୯ʹҧ൓͋ ΓͷίʔυΛ࡞ΕΔΑ͏ʹͳͬͨ w .JOJGZ͚ͩͰͳ͘3VCP$PQͷࣗಈमਖ਼όά ΋ݟ͚ͭͯ௚͢ػձʹͳ͍ͬͯΔ .JOJGZ։ൃͷࢥΘ͵෭࡞༻

Slide 81

Slide 81 text

0SJHJOBM$PEF

Slide 82

Slide 82 text

.JOJ fi FE$PEF

Slide 83

Slide 83 text

"VUPDPSSFDUFE$PEF .JOJGZͷத֩ͷίʔυΛ.JOJGZͯ͠ɺͦͷ͋ͱ3VCP$PQͰϑΥʔϚοτ

Slide 84

Slide 84 text

%&.0

Slide 85

Slide 85 text

w ࠓճͷ෮߸ԽσϞͷͨΊʹ΋͍͔ͭ͘௚ͨ͠ w ;ͭ͏ਓ͸ॻ͔ͳ͍ϫϯϥΠφʔʹରͯ͠ɺ 3VCP$PQ͸࿬͕؁͍ ͦΕ͸ͦ͏ w .JOJGZ͸ແݶʹ໰୊ΛᖰΓग़ͨ͢Ίͷڰؾͷ ڟث͔΋͠Εͳ͍ ਓ͕ॻ͔ͳ͍ίʔυΛಘΔ ਓ͸৘ཧͰ͖Ε͍ͳίʔυΛॻ͜͏ͱ͢Δ͕ɺϓϩάϥϜ͸ࢦࣔ௨Γಈ͚ͩ͘

Slide 86

Slide 86 text

PTSL@FGGFDU Ϛονϙϯϓͷ׬੒ .JOJGZΛ࡞ͬͨΒ3VCP$PQͷࣗಈमਖ਼ΫΦϦςΟ͕͕͋ͬͨ

Slide 87

Slide 87 text

l ੒ख़ͨ͠จԽɺྫ͑͹ԻָͰ΋ָේΛٯ͞ʹͯ͠ ΋஄͘͜ͱ͕Ͱ͖ΔԻָͱ͔ͦ͏͍͏΋ͷ͕͋ͬ ͯɺ தུ ੒ख़ͨ͠จԽʹ͸͜͏͍͓ͬͨ༡ͼ ͕ൃల͍ͯͯ͠ɺϓϩάϥϛϯάͱ͍͏෼໺΋ ੒ख़ͨ͠จԽʹͳ͍ͬͯΔͱ͍͑ΔΜͰ͔͢Ͷ !LJOBCB TRICK 2018 (FINAL) ʹͯ

Slide 88

Slide 88 text

Կͷ໾ʹ΋ཱͨͳ͍ ϓϩάϥϜΛָ͠ΉจԽ IUUQTXXXZPVUVCFDPNXBUDI W5#ON((VV