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
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
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
810
Exploring RuboCop with MCP
koic
0
5.5k
Ruby and LLM Ecosystem 2nd
koic
1
2.2k
STYLE
koic
0
2.2k
Ruby and LLM Ecosystem
koic
3
13k
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.8k
Other Decks in Programming
See All in Programming
AI 輔助遺留系統現代化的經驗分享
jame2408
1
250
TAKTでAI駆動開発の品質を設計する
j5ik2o
7
1.3k
Java × distroless で 軽量なコンテナイメージを / Java on Distroless
contour_gara
0
550
Lemonade + Foundry Toolkit でお手軽アプリ開発
seosoft
1
350
決定論的オーケストレーションの設計と実装 / Design and Implementation of Deterministic Orchestration
nrslib
4
1.4k
TypeScript+Orvalで実現する型安全かつ堅牢でスケーラブルなマルチチャネル通知基盤 / TSKaigi Night talks ~after conference~
d0riven
0
340
過去最大のMCPアップデート! 2026-07-28 RC版の謎に迫る
licux
6
360
Datadog × OpenTelemetry 入門と実践のあいだ
kn_to_maxpno
1
160
Lessons from Spec-Driven Development
simas
PRO
0
210
TSKaigi Night Talks 2026_TypeScriptでサプライチェーンの整合性を型に閉じ込める
geekplus_tech
0
390
LLMによるContent Moderationの本番運用の裏側と品質担保への挑戦
suikabar
3
700
Signal Forms: Details & Live Coding @enterJS 2026 in Mannheim
manfredsteyer
PRO
0
140
Featured
See All Featured
Fireside Chat
paigeccino
42
4k
The Power of CSS Pseudo Elements
geoffreycrofte
82
6.3k
The Language of Interfaces
destraynor
162
27k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.5k
The Impact of AI in SEO - AI Overviews June 2024 Edition
aleyda
5
1.1k
Building a Modern Day E-commerce SEO Strategy
aleyda
45
9.1k
Navigating Team Friction
lara
192
16k
Ruling the World: When Life Gets Gamed
codingconduct
0
250
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
2k
Technical Leadership for Architectural Decision Making
baasie
3
410
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2.3k
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
62
44k
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