Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Minify Ruby Code
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Koichi ITO
August 04, 2024
Programming
2.7k
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 Rails Doctrine Decade
koic
2
630
Reframing the Agile Manifesto
koic
5
4.9k
The NotImplementedError Problem in Ruby
koic
1
2.1k
Exploring RuboCop with MCP
koic
0
8.5k
Ruby and LLM Ecosystem 2nd
koic
1
2.3k
STYLE
koic
1
2.2k
Ruby and LLM Ecosystem
koic
3
14k
Write Code Every Day
koic
1
2.8k
Bliki (ja), and the Cathedral, and the Bazaar
koic
7
3.3k
Other Decks in Programming
See All in Programming
学びを記事・スライド・Xへ高速展開する― AI-assisted Learning Loopで回すコンテンツ生成術
ochtum
0
140
Jetpack Compose Mechanisms
skydoves
3
870
クラウドエージェントは、 何がそんなに便利なのか / what makes cloud agents so useful
rkaga
3
500
HTML-in-Canvasで作る未来のWeb UI表現
clockmaker
5
5.7k
全ての永続トークンを、生まれる前に消し去りたい!
sylph01
2
1.2k
コーディング自動化の次へ。人の介入をゼロにするファクトリーとサポートAIによる実践
timakin
5
4.6k
JIS keyboard support in Omarchy
lef237
0
160
sbt 2.0: takeoff
eed3si9n
0
170
[Dev Group Paris Octobre 26] Agentforce, SIforce, Claudeforce, Slackbot… on s'y retrouve ?
nabondance
0
120
Web Framework Benchmark Battle 2026, Any%
a_matsuda
3
2.9k
3回つくってわかった、 定期実行ジョブ基盤の本質情報
takai
4
3.1k
PyConTW 2026 - AI Coding 不只是工具升級, 區域醫院醫療資訊系統協作開發與資訊團隊轉型實踐
cclai999
0
180
Featured
See All Featured
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
123
22k
Joys of Absence: A Defence of Solitary Play
codingconduct
1
550
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
420
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
56
3.5k
Become a Pro
speakerdeck
PRO
31
6.3k
Groundhog Day: Seeking Process in Gaming for Health
codingconduct
0
440
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
290
Winning Ecommerce Organic Search in an AI Era - #searchnstuff2025
aleyda
2
2.2k
Kristin Tynski - Automating Marketing Tasks With AI
techseoconnect
PRO
0
560
<Decoding/> the Language of Devs - We Love SEO 2024
nikkihalliwell
1
360
The #1 spot is gone: here's how to win anyway
tamaranovitovic
4
1.2k
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