Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Minify Ruby Code
Search
Koichi ITO
August 04, 2024
Programming
2.6k
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Minify Ruby Code
大阪Ruby会議04 (
https://regional.rubykaigi.org/osaka04/
)
Koichi ITO
August 04, 2024
More Decks by Koichi ITO
See All by Koichi ITO
The NotImplementedError Problem in Ruby
koic
1
610
Exploring RuboCop with MCP
koic
0
5k
Ruby and LLM Ecosystem 2nd
koic
1
2.2k
STYLE
koic
0
2.2k
Ruby and LLM Ecosystem
koic
3
12k
Write Code Every Day
koic
1
2.6k
Bliki (ja), and the Cathedral, and the Bazaar
koic
7
3.1k
Welcome to the LLM Club
koic
0
410
RuboCop: Modularity and AST Insights
koic
3
5.7k
Other Decks in Programming
See All in Programming
PHPで使える日時の表現と、その知り方 #frontend_phpcon_do
o0h
PRO
0
190
Datadog × OpenTelemetry 入門と実践のあいだ
kn_to_maxpno
1
150
生成AI時代にこそ効くGo | Why Go Works in the Age of Generative AI
mom0tomo
8
3.1k
AIとASP.NET Coreで雑Webアプリを作った話
mayuki
0
340
エージェンティックRAGにAWSで入門しよう!
har1101
8
1.1k
AIチームを指揮するOSS「TAKT」活用術 / How to Use “TAKT,” an OSS Tool for Orchestrating AI Teams
nrslib
6
830
The Arts and Crafts of Work in the AI Era — Toward Mastery in Software Development
kuranuki
1
720
OSもどきOS
arkw
0
450
net-httpのHTTP/2対応について
naruse
0
440
RTSPクライアントを自作してみた話
simotin13
0
490
Spec-Driven Development with AI-Agents: From High-Level Requirements to Working Software
antonarhipov
2
450
Signal Forms: Beyond the Basics @ngBaguette 2026 in Paris
manfredsteyer
PRO
0
230
Featured
See All Featured
The Curious Case for Waylosing
cassininazir
1
370
Documentation Writing (for coders)
carmenintech
77
5.4k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
38
2.9k
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
320
Ethics towards AI in product and experience design
skipperchong
2
300
Git: the NoSQL Database
bkeepers
PRO
432
67k
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
140
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
170
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
8.2k
[SF Ruby Conf 2025] Rails X
palkan
2
1.1k
Build The Right Thing And Hit Your Dates
maggiecrowley
39
3.2k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
10k
Transcript
େࡕ3VCZձٞ த೭ౡϑΣεςΟόϧλϫʔɾΣετ ,PJDIJ*50&4. *OD .JOJGZ3VCZ$PEF Ruby Code Golf
with Practical Code
@koic w044ϓϩάϥϚʔ w3VCP$PQίΞνʔϜίϛολʔ wגࣜձࣾӬγεςϜϚωδϝϯτ &4. *OD ΤϯδχΞϦϯάϚωʔδϟʔ σΟεςΟϯάΠογϡυɾΤϯδχΞ
3VCZηϛφʔ౦ژ ݄ ۚ σϑΥϧτʹ͍ۙઃఆͰ͔͑ͬͯಡΈʹ͍͘मਖ਼Λ͍ͯ͠ΔํͷώϯτΛ
None
Support OSS community
w !LPJD1BSTFSHFNίϛολʔ w !KVOL-SBNBίϛολʔ w !4)(".&-*/,4QBSTFZίϯτϦϏϡʔλ w !GVHBLLCO3#4ίϯτϦϏϡʔλ w ෦һืूதʂ
ߏจղੳثݚڀ෦ IUUQTNBHB[JOFSVCZJTUOFUBSUJDMFT'PMMPX6Q,JSJTIJNB3VCZIUNM
None
.JOJGZ3VCZ$PEF ڝٕϓϩάϥϛϯάͰΈΔ 3VCZͷ๛͔͞ ʮಈ࡞͢Δ͖Ε͍Ͱͳ͍ίʔυʯͷ ࣄͰͦΜͳඪΛܝ͛·ͤΜͷͰ҆͝৺͍ͩ͘͞ dLPJD dIBSVHVDIJ
ʰ-3Ͱ+40/ύʔαʔΛ࡞Δʱ w dKVOL 1SFNJVN4QPOTPS w dIBSVHVDIJ w dLPJD "TLUIF4QFBLFST ग़ுʂߏจղੳثݚڀ෦
4QPOTPS-5 ݚᮎ3VCZϓϩάϥϛϯά ٳܜ࣌ؒʹϒʔε ͰखചΓ͞Ε·͢ ԿͰങ͓͏ʂ
ࠓͷ
None
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ͳͲͰ͓खݩʹΠϯετʔϧ
.JOJGZͷݱ࣮ͱՄೳੑ 1SJTN"1*ͱ-FYFS .JOJGZ3VCZ$PEF ࣍
.JOJGZͷݱ࣮ͱՄೳੑ
w ιʔείʔυͷαΠζΛখ͘͢͞Δ w 8FCͷੈքͰɺ)5.- +BWB4DSJQU $44 ͳͲϦιʔεͷωοτϫʔΫసૹྔΛݮΒ͢ w ϓϩάϥϛϯάݴޠͷ.JOJGZπʔϧͱͯ͠ɺ ྫ͑+BWB4DSJQUͰ6HJMJGZ+4
5FSTFSͳͲ .JOJGZͱʁ
+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͢Δ εϖʔεͷ߹ʹ͖࣮ͭࡍߦ
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ͷ݁ՌΛϓϩηεஔͰ࣮ߦͨ݁͠Ռ
w ಉ͡ৼΔ͍ͳΒ͍ํ͕ྑ͍ w ܭࢉػʹͱͬͯίʔυՄಡੑॏཁͰͳ͘ɺ ωοτϫʔΫసૹΛқ͘͢͠Δͷ͕࣮ફత w લड़ͷαϯϓϧίʔυͰʹѹॖ͞ΕΔ .JOJGZͷՁ؍ $ wc
-c greet.js 120 greet.js $ npx terser greet.js | wc -c 80
w $PNQSFTTɺෆཁͳεϖʔείϝϯτͷ আɺߏจͷॖԽʹΑͬͯɺϓϩάϥϜ ͷ͍ͨΔՕॴΛ͘͢Δ ຊฤ͜ͷҰ෦ w .BOHMFม໊໊ؔΛॖ͢Δ w ಉ͡ৼΔ͍ͷ··ʮѹྗʯ͕ΑΓ
ߴ͍ํ͕ɺΑΓՁ͋Δ͍ίʔυ $PNQSFTTͱ.BOHMF
ͦͦͳͥ .JOJGZ
w 3BJMTΞϓϦέʔγϣϯͷσϓϩΠΛಛఆͷ αʔόʔʹߦͳ͍ɺͦ͜ʹରͯ͠ϦΫΤετ ͕ूத͢ΔݱͰແԑ w ͠.JOJGZࡁΈίʔυ͕σϓϩΠ͞ΕΔͱɺ ͕ى͖ͨͱ͖ߦ൪߸͕ࢦ͔͢ΒՕॴ ͷಛఆ͕ࠔʹͳͬͯࠔΔ ͦΕͦ͏ ݱͷ͓ࣄ3VCZͩͱͲ͏ʁ
w ໝͦͷɻSVCZXBTNͷίʔυͰ֎෦Ϧιʔ εΛཁٻͨ͠ࡍʹɺ*4FRͳͲͷதؒදݱͰͳ͍ QMBJOͳ3VCZίʔυͷωοτϫʔΫసૹྔݮʁ w ໝͦͷɻΤοδίϯϐϡʔςΟϯάͰɺΤο δαʔόʔ $%/ ΤοδσόΠε *P5
ͷ ίϯςϯπσʔλͷʹ͓͍ͯ༗༻ʁ ະདྷͷ͓ࣄ3VCZͩͱͲ͏ʁ NJOJGZ1JDP3VCZͷϝϞϦݮʹ͑ΔͣͳͷͰ͍ͯ͠·͢ɻ IUUQTYDPNIBTVNJLJOTUBUVT
w དྷ3VCZ,BJHJ দࢁ Ͱ53*$, ͕։࠵͞ΕΔΒ͍͠Ͱ͢Αʁ w ࣄ044Ͱࢦ͍ͯ͠Δʮಈ࡞͢Δ͖Ε͍ ͳίʔυʯͰͳ͍෯Λ࡞ΔػձॏཁͰʁ w .JOJGZ͢Δͷʹʮιʔείʔυͷղੳʯ͕
ඞཁͰͦΕ͢ͳΘͪɺ͍·ྲྀߦΓͷʂʁ དྷͷ3VCZΠϕϯτͩͱͲ͏ʁ
ߏจղੳث .BU[ݴ͍·ͨ͠ύʔαʔͱ($ͱίʔυδΣωϨʔλʹۙͮ͘ͳ
1SJTN"1*Ͱιʔεղੳ
ࣈ۟ղੳͱߏจղੳͷར༻ྫ ࣈ۟ղੳ ߏจղੳ ੩తղੳ Ϩϙʔτ ιʔείʔυ ೖྗ ॲཧ ग़ྗ
w τʔΫϯྻιʔείʔυΛࠨ͔ΒӈʹಡΜͩ τʔΫϯͷྻ w ߏจϓϩάϥϜͷߏจߏΛϊʔυͱͯ͠ πϦʔߏͰදݱ͍ͯ͠Δ w ྫ͑ΫϥεఆٛͷϊʔυͷԼʹϝιουఆٛͷ ϊʔυ͕͋ΔͳͲߏจͷํ͕๛͔ͳσʔλߏ τʔΫϯྻͱߏจ
w γϯϘϧΛҾʹͨ͠ϝιουݺͼग़͠ τʔΫϯྻͷαϯϓϧ puts :hello [:IDENTIFIER, :SYMBOL_BEGIN, :IDENTIFIER, :EOF] puts
: hello %w(foo) [:PERCENT_LOWER_W, :STRING_CONTENT, :STRING_END, :EOF] w ཁૉͻͱͭͷXϦςϥϧ %w( foo )
ߏจͷαϯϓϧ $ 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ΛಘΔ
ߏจ ࠓճׂѪ ࠓ͖ͬͱۚࢠ͞Μ͕ࢁ͍ͯ͠Δʂ
w 3VCP$PQͷΑ͏ʹߏจͷैଐؔΛࠪ͠ ͯɺΦʔτίϨΫτͰߏจॻ͖͍͑ͨ͠Α ͏ͳέʔεߏจΛѻ͑ͳ͍ͱ͍͠ w ࠓճͷ.JOJGZͰجຊతʹߏจΛॻ͖͑ ͳ͍ͷͰɺτʔΫϯྻͰेͱ͍͏அ τʔΫϯྻͱߏจͷ͍͚ ͬ͘͟Γ͍͏ͱߏจߏͷॲཧ͢ΔͱͳͬͨΒߏจ͕ཉ͘͠ͳΔ
ࠓճτʔΫϯྻ
w Ripper.lexͱPrism.lex͍ͣΕϓϩάϥϜ ͷτʔΫϯྻΛखʹೖΕΔ͜ͱ͕Ͱ͖Δ"1* w ͔ͤͬ͘ͳͷͰɺ·ͩใ͕গͳ͍1SJTNΛͬ ͯΈͨํ͕͓͠Ζͦ͏ ϓϩϙʔβϧతʹ w Prism.lex_ripperͱPrism.lex_compat
3JQQFSʹ͍ۙ"1*͕ͩɺࠓճૉʹPrism.lex 3VCZͷτʔΫϯऔಘ"1*બఆ
1SJTNMFYͷجຊ"1*
w Prism.lexϝιουͰղੳ݁ՌΛද͢ Prism::LexResultΦϒδΣΫτΛಘΒΕΔ w 📝1SJTN·ͰPrism::ParseLexResult Λޡͬͯฦͯ͠Δ ৄ͘͠SVCZQSJTN 1SJTNMFY require 'prism'
result = Prism.lex('puts :hello') result.class #=> Prism::LexResult
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 #=> [#<Prism::Token>, 32] IUUQTHJUIVCDPNSVCZQSJTNCMPCWJODMVEFQSJTNQBSTFSI--
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
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
τʔΫϯॲཧͷఆੴαϯϓϧ 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ͷछྨͰॲཧΛผ͢Δ ࠨ͔ΒӈͷτʔΫϯྻͷϧʔϓ
ࣈ۟ղੳͱߏจղੳͷར༻ྫ ࣈ۟ղੳ ߏจղੳ ѹॖॲཧ ѹॖ͞Εͨίʔυ ιʔείʔυ ೖྗ ॲཧ ग़ྗ
.JOJGZ3VCZ$PEF
github.com/koic/minifyrb
w minifyrbίϚϯυͰɺෆཁͳίʔυ෦ɺ ͭ·ΓτʔΫϯΛআڈͯ͠ίʔυΛѹॖ͢Δ .JOJGZ3VCZHFN $ gem i minifyrb $ echo
"puts :hello" | minifyrb puts:hello
0SJHJOBM$PEF
.JOJ fi FE$PEF
ઃܭํ
w ͳͯ͘ྑ͍ۭനվߦΛۃྗআڈ͢Δ w ίϝϯτΛআڈ͢Δ w ඞཁʹԠͯ͡ηϛίϩϯʹΑΔϫϯϥΠφʔ w ม໊ϝιου໊Λॖ͢Δ.BOHMF ෳࡶʹͳΔͨΊߦΘͳ͍ ࠓޙͷల
ݱ࣌ͷجຊతͳߟ͑ํ
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} εϖʔεɺηϛίϩϯෆཁ ಡΈ͢͞ͷվߦΛ͢Δ
w FOEϕʔεͷߏจͱͳΔ3VCZͰྫ͑վߦ Ληϛίϩϯʹஔ͖͑ͯɺ݁ہόΠτ ͷαΠζֻ͕͔Δ͜ͱมΘΒͳ͍ w FOE^ͱൺɺ۠Γεϖʔε͕ඞཁ͔அ w ॳσόοά࣌ͷߦ൪߸ΛΔҙຯͰɺ ෳߦͷ··Ͱྑ͍ͱ͍͏τϨʔυΦϑஅ 3VCZͷϫϯϥΠφʔ
ِ 1όΠτ
w FOEϕʔεͷߏจͱͳΔ3VCZͰྫ͑վߦ Ληϛίϩϯʹஔ͖͑Δͱɺ8JOEPXTͳΜ ͔ͷaSaOͷόΠτվߦόΠτʹݮΒͤΔ w .JOJGZͱ͍͏ํʹ͓͚ΔτϨʔυΦϑஅ ੑΑΓ͍ίʔυΛऔΔ w ݁Ռͱͯ͠෭࡞༻ʹएׯͷಡԽ͕͍͖ͭͯͨ 3VCZͷϫϯϥΠφʔ
ਅ
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" [[#<Prism::Token:0x0000000104c87b70 @source=#<Prism::ASCIISource:0x000000011f7f5dd0 ͍ͭ͜ಈͧ͘ʂ
w .JOJGZ-41ͷΑ͏ͳೖྗ్தͷίʔυΛॲཧ ͢ΔͷͰͳ͍ w ಈ͔ͳ͍ίʔυΛ.JOJGZͯ͠ํͳ͍ͷͰɺ ݩίʔυ͕ߏจΤϥʔͷͱ͖Τϥʔͱͨ͠ w Prism.lex(code).errorsͷ݁Ռྻ Prism.parse_success?ͰΔ͜ͱ͕Ͱ͖Δ &SSPS5PMFSBODFͷஅ
Prism::ParseLexResult#errors
τʔΫϯॲཧͷ࣮
w *(/03&%@/&8-*/&ଥͳγϯλοΫ εͰ͋ΔͨΊʹෆඞཁͳվߦ ୯ʹআՄೳ w /&8-*/&ଥͳγϯλοΫεͰ͋Δͨ Ίʹඞཁͳվߦ ୯ʹআ͢ΔͱߏจΤϥʔ छྨͷվߦτʔΫϯ
ݱࡏͷ1SJTN ࣮ͩͱظͱҧ͏෦͋Γޙड़
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 ࢀߟผ్ηϛίϩϯஔ όΠτ
w ʮಈ࡞͢Δ͖Ε͍Ͱͳ ͍ίʔυʯ͕ຊτʔΫͷ ςʔϚͰ͢Α w .JOJGZͱ53*$,ີ ʹؔ࿈͢ΔԾઆ w 53*$,ͷLJOBCB͞ Μ࡞ͷཧղʹ͚ۙͮΔʁ
͜ͷτʔΫϯ͔ΒಘΒΕΔֶͼ IUUQTHJUIVCDPNUSJDUSJDLCMPCNBTUFSLJOBCBFOUSZSC 53*$,໊࡞ͷͻͱͭ
w "\r\n"͔͠Εͳ͍վߦΛ۠ΓτʔΫϯʹ ͢Δ͜ͱͰόΠτΛݮΒͤΔՄೳੑ͕͋Δ w *(/03&%@/&8-*/&ͱҧ͍ɺdef foo͕ deffooʹͳΒͳ͍Α͏దٓ۠Γௐ͕ඞཁ w ࣍τʔΫϯͷܕ͕&0'ͷ߹104*9४ڌͷ ςΩετϑΝΠϧͱ͢ΔͨΊվߦΛҡ࣋͢Δ
/&8-*/&τʔΫϯ
104*9४ڌҧ👮 (JU)VCͷΞϨ /&8-*/& &0'
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 ')'
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
վߦͷτʔΫϯॲཧ֓ཁ 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-*/&͔ͳύον
w )&3&%0$@45"35ͱ)&3&%0$@&/%ͷ τʔΫϯʹғ·ΕͨτʔΫϯ͕ຊจ )&3&%0$@ 45"35c&/% τʔΫϯ <<HEREDOC text HEREDOC [:HEREDOC_START,
:STRING_CONTENT, :HEREDOC_END, :NEWLINE, :EOF]
w γϯϓϧͳώΞυΩϡϝϯτͳΒ )&3&%0$@45"35͔Β)&3&%0$@&/%· ͰͷτʔΫϯΛ݁߹͢ΕऴΘΓͦ͏ w τʔΫϯྻιʔείʔυΛࠨ͔ΒӈʹಡΜ ͩ݁Ռͷྻͱݴͬͨͳʁ ώΞυΩϡϝϯτ
w :DOT, :IDENTIFIER:HEREDOC_STARTʹ ଓ͘τʔΫϯͰͳ͍ w ώΞυΩϡϝϯτΛจࣈྻϦςϥϧͷҰछͩͱࢥ ͑"text".do_somethingͳͷͰͦΕͦ͏ )&3&%0$EP@TPNFUIJOH <<HEREDOC.do_something text
HEREDOC [:HEREDOC_START, :STRING_CONTENT, :HEREDOC_END, :DOT, :IDENTIFIER, :NEWLINE,:EOF]
w ͍όΠτʹ͢Δํʹج͖ͮIFSFEPD จࣈྻϦςϥϧʹஔ͢Δ͜ͱͱͨ͠ w )&3&%0$@45"35͔Β)&3&%0$@&/%· ͰώΞυΩϡϝϯτͰ͋Γɺdͷ߹ IFSFEPDऴྃͰEFEFOU͢ΔΑ͏ঢ়ଶΛอͭ )&3&%0$EP@TPNFUIJOH <<HEREDOC.do_something text
HEREDOC " 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ຊจͷτʔΫϯͷྻΛ݁߹
ͯ͢ΛޠΔλΠτϧɻࠓճͷHFNIFSFEPD͕ਖ਼·ͩόΪʔ IUUQTTQFBLFSEFDLDPNZVJ@LOLIFSFEPDJOEFNPODBTUMF
ࠓޙͷ֦ுʹ͚ͨҙ def m(a) bar unless cond end def m(a)bar unless
cond end w ҾΧοί͋Γͷɺվߦηϛίϩϯͳ͠Ͱॻ͚ΔFOE͋Γͷ ϫϯϥΠφʔϝιουఆٛʹ͍ͭͯߟ͑Δ ಉ͡ߏจ
FOEMFTTEFGͱߏจ͕ҟͳΔ w .BOHMJOHΛߟ͑Δ߹-FYFSτʔΫϯΑΓ ߏจͰͷॲཧ͕͍͍ͯΔ͔ def foo(a)=bar unless cond def foo(a)bar
unless cond end ҟͳΔߏจ
ެ։ ͜ΜͳࢥߟΛͭͭ͠Ͱ͖·ͨ͠
# 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ͰͲΕ͘Β͍ݮΔʁ
w MJC όΠτ͔Β όΠτʹͳΓɺ TQFD όΠτ͔Β όΠτʹ ͳΔ w ͭ·Γݮ͞Εͨίʔυ34QFDͷํ͕ߴ͍
w ࣮ફత ͱʁ ʹϓϩμΫτίʔυͷޮ Ռ͕ߴ͍ํ͕͍͍Μ͚ͩͲݱ࣮͜͏Β͍͠ ଌఆͱධՁΛ͏গ͠
github.com/koic/minifyrb gem install minifyrbͰ༡ΜͰΈͯͶ
͓΅͍͑ͯ·͔͢ʁ
@koic w044ϓϩάϥϚʔ w3VCP$PQίΞνʔϜίϛολʔ wגࣜձࣾӬγεςϜϚωδϝϯτ &4. *OD ΤϯδχΞϦϯάϚωʔδϟʔ σΟεςΟϯάΠογϡυɾΤϯδχΞ
One More Thing
" ࠞಱͱடং
.JOJGZͨ͠ίʔυͱ ͬͱٔΕΔ
w ಡԽʹର͢Δ෮߸ԽΈ͍ͨͳͷ w ͓ࣄʹݶΒͣɺ;ͩΜΈΜͳߦّͷྑ͍ ίʔυΛແҙࣝʹࢦͯ͠͠·͍·͢ΑͶʁ w 3VCP$PQͷΦʔτίϨΫτͱ͍͏ ϑΥʔϚολʔͷྗͷ࠶ൃݟ .JOJGZͰյͯ͠3VCP$PQͰ͢ .JOJGZͨ͠ίʔυ͕Ͳ͏෮ݩͰ͖Δ͔ڵຯΛ࣋ͪ·͢ΑͶʁ
w .JOJGZͱ3VCP$PQͱ͍͏ࠞಱ͔Βͷ w 3VCP$PQͷΤοδέʔεॲཧʹ͍ͭͯɺ NJOJGZͨ͠ίʔυΛݩʹ͢Ε؆୯ʹҧ͋ ΓͷίʔυΛ࡞ΕΔΑ͏ʹͳͬͨ w .JOJGZ͚ͩͰͳ͘3VCP$PQͷࣗಈमਖ਼όά ݟ͚ͭͯ͢ػձʹͳ͍ͬͯΔ .JOJGZ։ൃͷࢥΘ͵෭࡞༻
0SJHJOBM$PEF
.JOJ fi FE$PEF
"VUPDPSSFDUFE$PEF .JOJGZͷத֩ͷίʔυΛ.JOJGZͯ͠ɺͦͷ͋ͱ3VCP$PQͰϑΥʔϚοτ
%&.0
w ࠓճͷ෮߸ԽσϞͷͨΊʹ͍͔ͭͨ͘͠ w ;ͭ͏ਓॻ͔ͳ͍ϫϯϥΠφʔʹରͯ͠ɺ 3VCP$PQ͕͍ ͦΕͦ͏ w .JOJGZແݶʹΛᖰΓग़ͨ͢Ίͷڰؾͷ ڟث͔͠Εͳ͍
ਓ͕ॻ͔ͳ͍ίʔυΛಘΔ ਓཧͰ͖Ε͍ͳίʔυΛॻ͜͏ͱ͢Δ͕ɺϓϩάϥϜࢦࣔ௨Γಈ͚ͩ͘
PTSL@FGGFDU Ϛονϙϯϓͷ .JOJGZΛ࡞ͬͨΒ3VCP$PQͷࣗಈमਖ਼ΫΦϦςΟ͕͕͋ͬͨ
l ख़ͨ͠จԽɺྫ͑ԻָͰָේΛٯ͞ʹͯ͠ ͘͜ͱ͕Ͱ͖ΔԻָͱ͔ͦ͏͍͏ͷ͕͋ͬ ͯɺ தུ ख़ͨ͠จԽʹ͜͏͍͓ͬͨ༡ͼ ͕ൃల͍ͯͯ͠ɺϓϩάϥϛϯάͱ͍͏ ख़ͨ͠จԽʹͳ͍ͬͯΔͱ͍͑ΔΜͰ͔͢Ͷ !LJOBCB TRICK
2018 (FINAL) ʹͯ
Կͷʹཱͨͳ͍ ϓϩάϥϜΛָ͠ΉจԽ IUUQTXXXZPVUVCFDPNXBUDI W5#ON((VV