Slide 1

Slide 1 text

Transcendental Programming in Ruby Yusuke Endoh (@mametter) Cookpad Inc. Keep Ruby Weird 2018 (2018/11/09)

Slide 2

Slide 2 text

Yusuke Endoh (@mametter) • A MRI committer (2008..) – Keyword arguments – Test suite improvement – coverage.so (backend of SimpleCov) – OptCarrot: A benchmark for Ruby3x3 • Working at Cookpad Inc. – As a full-time Ruby committer (with Koichi Sasada)

Slide 3

Slide 3 text

• A recipe sharing platform service – Monthly Average Users: 90 million – https://cookpad.com/uk PR: Cookpad Inc. We're hiring! HQ is in Bristol Aim to be No.1 in 100 countries (Now in 22 Languages and 68 Countries)

Slide 4

Slide 4 text

Transcendental programming • Enjoy programming regardless of practicality – Forget usefulness, secular benefits, and the weary world, and just do programming – Abuse a useful programming language to write a completely useless program

Slide 5

Slide 5 text

A Ruby program require "doublehelix" AT A--T T---A G----C G----C G----C T---A G--C AT GC T--A G---C T----A A----T T----A G---C C--G AT CG A--T A---T C----G A----T G----C G---C G--C CG GC A--T T---A C----G G----C A----T T---A C--G GC TA T--A C---G G----C A----T T----A C---G require "doublehelix" AT A--T T---A G----C G----C G----C T---A G--C AT GC T--A

Slide 6

Slide 6 text

Demo • "Hello, world!" program in doublehelix – You can encode not only Hello world, but also any Ruby programs $ ruby doublehello.rb Hello-hello! doublehelix

Slide 7

Slide 7 text

Internal • Gödel numbering – Converts a program text to a number • Text to number: str.unpack("H*")[0].hex • Number to text: [num.to_s(16)].pack("H*") • Double-helix encoding and decoding doublehelix

Slide 8

Slide 8 text

Internal: Double-helix encoding • Convert the number in binary notation • And each two digits to AT/CG/GC/TA doublehelix 0000111010... puts"Hello-hello!" Gödel numbering 00 00 11 10 10 AT AT TA GC GC AT A--T T---A G----C G----C ...

Slide 9

Slide 9 text

Internal: Double-helix decoding • const_missing – Restore the number, decode it to the code, and eval • One more trick is needed... doublehelix Object.instance_eval{ def const_missing(sym) p sum end } remove_const(:GC) AT #=> :AT A--T #=> :A, :T T---A #=> :T, :A G----C #=> :G, :C G----C #=> :G, :C

Slide 10

Slide 10 text

How to install – Acknowledge: This program was inspired by Perl's Acme::DoubleHelix doublehelix $ gem install doublehelix

Slide 11

Slide 11 text

QR code?

Slide 12

Slide 12 text

Scanned result #!ruby # Q(uine)R(uby)code (C) Y.Endoh 2009 eval s=%q(X=(0..7).map{|i|1<8?14:i>7?15:W)-i]=26998[i];i<18&&m[i/3][x=i%3+106 ]=m[x][i/3]=102881[i];i<26&&g=(g+[0]).zip([0]+g.map{|x|X[i+X.index(x)]}).map{| x,y|x^y}}][8]=1;_,*G=g;n=c=12704;b=("404e4#{"%02x"*1252}0#{"ec11"*B}"%%(#!ruby # Q(uine)R(uby)code (C) Y.Endoh 2009¥neval s=%q(#{s})).unpack("C*")).scan /../ D=[];E=([106]*8+[107]*4).map{|d|D<

Slide 13

Slide 13 text

Q(uine)R(uby) code #!ruby # Q(uine)R(uby)code (C) Y.Endoh 2009 eval s=%q(X=(0..7).map{|i|1<8?14:i>7?15:W)-i]=26998[i];i<18&&m[i/3][x=i%3+106 ]=m[x][i/3]=102881[i];i<26&&g=(g+[0]).zip([0]+g.map{|x|X[i+X.index(x)]}).map{| x,y|x^y}}][8]=1;_,*G=g;n=c=12704;b=("404e4#{"%02x"*1252}0#{"ec11"*B}"%%(#!ruby # Q(uine)R(uby)code (C) Y.Endoh 2009¥neval s=%q(#{s})).unpack("C*")).scan /../ D=[];E=([106]*8+[107]*4).map{|d|D<

Slide 14

Slide 14 text

Internal • Quine (& QR-encoder, PNG-generator) #!ruby # Q(uine)R(uby)code (C) Y.Endoh 2009 eval s=%q(X=(0..7).map{|i|1<8?14:i>7?15:W)-i]=26998[i];i<18&&m[i/3][x=i%3+106 ]=m[x][i/3]=102881[i];i<26&&g=(g+[0]).zip([0]+g.map{|x|X[i+X.index(x)]}).map{| x,y|x^y}}][8]=1;_,*G=g;n=c=12704;b=("404e4#{"%02x"*1252}0#{"ec11"*B}"%%(#!ruby # Q(uine)R(uby)code (C) Y.Endoh 2009¥neval s=%q(#{s})).unpack("C*")).scan /../ D=[];E=([106]*8+[107]*4).map{|d|D<

Slide 15

Slide 15 text

Quine • A program that outputs itself – Step 1. Reconstruct self as a string – Step 2. Print it • Additional step makes Quine "funny" eval s="print('eval s='+s.inspect)" Q(uine)R(uby) code

Slide 16

Slide 16 text

Quine + QR-enc. + PNG-gen. Q(uine)R(uby) code eval s="print( generate_PNG( encode_QR( 'eval s='+s.inspect ) ) )"

Slide 17

Slide 17 text

What is this? eval s=%w(0;y=""< <32;z="eval((;s=%w(#{s} )*''));; %" <<43< >3*i- =48).g sub(/. /){s>$ &?y*3: z.slic e!(0,3 )}}*y<<1 0}};puts (d.strip.chop<<43))*''# #(c) Y.Endoh 2009

Slide 18

Slide 18 text

Demo • It tells time as a code that tells time $ ruby qlock.rb eval(( ;s=%w(0;y =""<<32;z ="eval((; s=%w(#{s} )*''));;% "<<43< >3 *i- =48 ).g sub (/. /){ s>$&?y*3: z.s lic e!( 0,3 )}} *y< <10 }}; put s(d .st rip .ch op< <43 ))* '') );; %+0 ;y= ""< <32 ;z= "ev al( (;s =%w (#{ s}) *'' )); ;%" <<43<

Slide 19

Slide 19 text

Internal (digest) • Quine + Font + Executable ASCII-art eval s=%w(0;y=""< <32;z="eval((;s=%w(#{s} )*''));; %" <<43< >3*i- =48).g sub(/. /){s>$ &?y*3: z.slic e!(0,3 )}}*y<<1 0}};puts (d.strip.chop<<43))*''# #(c) Y.Endoh 2009 • Quine • Clock generator – Font data – ASCII-art generator • See my RubyConf talk for the details – https://www.youtube.com/ watch?v=6K7EmeptEHo Qlock

Slide 20

Slide 20 text

What is this? '';eval(r=%q(->z{r="'';eval(r=¥ %q(#{r}))[%q`#{z}`]";i=-040;30. times{|n|(15+n%2*15-n/2).times{ r<["t]];};o[1,?¥n*8];ex"-}eac 1Hl<1[-1]*2*t=n%2];o[14-n,0)mvk 8M$<4,?¥n];15.times{|n|;o[35ie2 !Pss.slice!(0,1)+x;sleep(0.0t;0 'W=%q"<<95<<$s<<95;o=->n,x{n.'1 ;@[2]}|¥e../,%@s="'%trick2018!8 eval$s=%q_eval($s.gsub!(/#{%@`]

Slide 21

Slide 21 text

DEMO Spiral Quine

Slide 22

Slide 22 text

Internal • Quine + Animation – Use escape sequence to move the cursor – The output includes many escape sequences, so not a valid Ruby code...? print "¥e[1A" #=> move up print "¥e[1B" #=> move down print "¥e[1C" #=> move right print "¥e[1D" #=> move left Spiral Quine

Slide 23

Slide 23 text

Music-box Quine eval$C=%q(at_exit{ open("/dev/dsp","wb"){|g|h=[0]*80 $><<"¥s"*18+"eval$C=%q(#$C);S=%:" (S<

Slide 24

Slide 24 text

DEMO Music-box Quine https://youtu.be/OryXKUgRVOg

Slide 25

Slide 25 text

Internal • Quine + Music player – Synthesize sound waves – And send them to the sound driver (/dev/dsp) eval$C=%q(at_exit{ open("/dev/dsp","wb"){|g|h=[0]*80 $><<"¥s"*18+"eval$C=%q(#$C);S=%:" (S<

Slide 26

Slide 26 text

Lipogram Quine format= %%->{#({#){#.{#0{#1{#2{#3{#4{#5{#6{#7{#8{#9{#h{#k{#l{#p{#v{#w{#<{#*{#a{#b{#c{#d{#e{#f{; t=->s,x,y{->&u{u[s,x,y]}[&:tr]};z="!-{";->&u{u[y="().0123456789hklpvw<*abcdef¥¥",t["m~i",",-~", "$-{"]+t["$",z,"i-{"],t[t["YQUO@g=`@W='@ABCDEFGHIJKLMNOPQRSTUVWXYZ';g=^YQUO@g=`@^+g+^AA^;Y=?=;n =Y+OoWUO_Q UriUVOYsTY+Y;x=- >s{sBVyt Ys};q,=n[u =^ZormUt^]?@u =ZormUtA?[ DC,TFEBBDEI]-x[u +?`]:x[W +?`]-x[y]: n=~/=Z?o?r?m? U?t?=/?x[u ]-x[$&]:Y;z='ZormUt= C``->{H{Dt=- >s,x,y {Js,x, y]}[&: tr]};z=^!-{ ^;Jy=^I^,t [^m~iK,-~K$-{^]+t[^$ ^,z,^i-{^],t [t[^EK C^+$/, ^^],^G ^,t[^qntuz| yKm-|^,z]+ t[^;jmnrxy>,K&-{K$-{ ^]+t[^o;tK/- {^,z]] ]}[&Jt [^xjsi K&-{^,z]]}[ &:to_sym]] }[]`;DYQUO^@YQUO@@`R ``SS`R`F`T`` `ABPUW N@``MT `AAA^' BgsuV@/[C-L ]/A{[FEBWM r,$/,gBtr@'`^'+W,j=L IBWMrSSLGSSI GSSGHSSL CA,TgB unPUWN@^MT^ A,j,?#+WBW MUrsT^{#^,W+LEBWMrTE ,^->&u{u[^,' ^,^'][YQ UO$&]} ;GGBtimYs{| y|Print@@@ CBBLGABmUP{|x|^qZXzm uDHjtVOCuVnO ooCYHWIJyrnonDmE GtijRU oNFxGWXxuOm CmIEYRXsgZ EgqOKQMGHJOKQnYuuVYy IrCEmrPqVgno irYDnnxLDjZWCGyN nZmnIy zKXignRYPnz DuCYgMHyyM JjqWYD ODruUPCm DtqFqFDCrrJVxXJzOg MWQGNnUuio^Bt o_i@FIA[x/ E-D+@y +DA/ETGI ]>C?@FEBWMrA:@z[C] ==$/||!z[C]?? ;:zBsOiWY!@C,DAA}T^^+$/ABtr@@!$T[C]&&q||CABWMr,^^AA;z[C]==$/&&z[C]=^^};Yxit;;;;;;;AA"," "+$/,"" ],"`^@-Z",t["qntuz|y","m-|",z]+t[";jmnrxy>,","&-{","$-{"]+t["o;t","/-{",z]]]}[&->&u{u[t["xjsi", "&-{",z]]}[&:to_sym]]}[]%;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; eval"(eval((%w%%<<%w%566716c68276d3528236d3728292e20313233343536373839386b6c6076777c3a216263646 566672b376d322566716c68276d3528222b276b222929222b356d3f3d3b3e6d356b2c6f63616c6f5671627961626c65 637a256b256b387d3d2e337b737e22697475637d7b317c2d3e6b557d32266f627d6164722d5f38257d366f627d61647 92f3b51303c2a23323e2e2132363d5d287b557b2f352d5a387b536b2f352d5d287b597d5a3e6d3e7f2d366f3f6f327f 3d6f316f347f3d3f2f387b557d5d287b54262d5a356b3a7d37266f627d61647d3035252d2e3b753b71347d3d2e337c2 87c297b77337c287c297d5d7b562a34727d5d7b3a7d32212d2b722b37397d3226322c247b522d6e79683c2d2e78342d 2b722d5b247b5224222c2a7c22296d2b722d5c247b547b52223830322b242f2c22222d5c2224322c247b52217e64757 a7c79783d6d2c7 22c2a7 d5b247b522b3 a6d6e62787 97e3c2 8362d2b7834 2d2b722d5b247b 522f6b 34783f2d2b72 2c2a7d5d5d 5d7b56 27347b52287 a637968362d2 b722c2a7d5d5d7 b562a3 47f6f537 97 d6d5d5d7 b5 d552b313566 716c62282566 716c6828252775 252c3c 35277523 35 2a252525 29 2e2071636b6 82525286a2 529292922272e276 375726 82f2b5 03d293 d5f292 b7b53323e23 68627c242f 2c276e2472782725 22272b 236c2a 6d3936 3e2368 627c3c39343 c3c36343c3 c343 53c3c3 930392 c2a276 e257e6 071636 b6 82 2286a22292c 2a6c2f332b 236e 236861 62737a 222b73 222c23 6b2932 3e 23 68627a223c2 22d2e36257 b757b5 22c272 22c22272d5 b55667 16 c6 4262d5d7b34 343e24796d 65637b 7c797c 7072796e64 782828 20 3e 2e2934392e2 d61607b7c787 c722 176646 a7d6 571353a6 4726c6 035726 e6c6f6 f6035653366 3739727e6f6e 613d 623434 796a 67716f6b 633874 336468 757c6d 603d6632356 77463776662376 17c683 678643 5373c6 8367e6 565757 265697 63270323d62 707172676e6f69 627561 3e6e68 79313a 666360 34397b 6e666d 6e66397a783 469676e6775607e6a71357035676865397978673a617365613c6132757160703d613471733173313032727732687467 3a7c67686366743b6e6165796f622e247f6f59682336392b587f223d213b28297b21392f223a24363d5e303f3823323 e236862792a382a7b503d5d3d342f2c7c712a7b503d5f3f3b3a3a7e237c6963656128203c2139292d7a22222b242f29 2e2472782821242a2b503d5626217c7c70392e2368627c222229292b3a7b503d5d3d342f26262a7b503d5d32222d7b3 56879647b3b3b3b3b3b3b39292%*%%%).pack(%%h*%)))";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Slide 27

Slide 27 text

Demo • Works as an ordinary Quine $ ruby lquine.rb > lquine2.rb $ diff –s lquine.rb lquine2.rb lquine.rb and lquine2.rb are identical Lipogram Quine

Slide 28

Slide 28 text

"a" is removed from the world! format= %%->{#({#){#.{#0{#1{#2{#3{#4{#5{#6{#7{#8{#9{#h{#k{#l{#p{#v{#w{#<{#*{#a{#b{#c{#d{#e{#f{; t=->s,x,y{->&u{u[s,x,y]}[&:tr]};z="!-{";->&u{u[y="().0123456789hklpvw<*abcdef¥¥",t["m~i",",-~", "$-{"]+t["$",z,"i-{"],t[t["YQUO@g=`@W='@ABCDEFGHIJKLMNOPQRSTUVWXYZ';g=^YQUO@g=`@^+g+^AA^;Y=?=;n =Y+OoWUO_Q UriUVOYsTY+Y;x=- >s{sBVyt Ys};q,=n[u =^ZormUt^]?@u =ZormUtA?[ DC,TFEBBDEI]-x[u +?`]:x[W +?`]-x[y]: n=~/=Z?o?r?m? U?t?=/?x[u ]-x[$&]:Y;z='ZormUt= C``->{H{Dt=- >s,x,y {Js,x, y]}[&: tr]};z=^!-{ ^;Jy=^I^,t [^m~iK,-~K$-{^]+t[^$ ^,z,^i-{^],t [t[^EK C^+$/, ^^],^G ^,t[^qntuz| yKm-|^,z]+ t[^;jmnrxy>,K&-{K$-{ ^]+t[^o;tK/- {^,z]] ]}[&Jt [^xjsi K&-{^,z]]}[ &:to_sym]] }[]`;DYQUO^@YQUO@@`R ``SS`R`F`T`` `ABPUW N@``MT `AAA^' BgsuV@/[C-L ]/A{[FEBWM r,$/,gBtr@'`^'+W,j=L IBWMrSSLGSSI GSSGHSSL CA,TgB unPUWN@^MT^ A,j,?#+WBW MUrsT^{#^,W+LEBWMrTE ,^->&u{u[^,' ^,^'][YQ UO$&]} ;GGBtimYs{| y|Print@@@ CBBLGABmUP{|x|^qZXzm uDHjtVOCuVnO ooCYHWIJyrnonDmE GtijRU oNFxGWXxuOm CmIEYRXsgZ EgqOKQMGHJOKQnYuuVYy IrCEmrPqVgno irYDnnxLDjZWCGyN nZmnIy zKXignRYPnz DuCYgMHyyM JjqWYD ODruUPCm DtqFqFDCrrJVxXJzOg MWQGNnUuio^Bt o_i@FIA[x/ E-D+@y +DA/ETGI ]>C?@FEBWMrA:@z[C] ==$/||!z[C]?? ;:zBsOiWY!@C,DAA}T^^+$/ABtr@@!$T[C]&&q||CABWMr,^^AA;z[C]==$/&&z[C]=^^};Yxit;;;;;;;AA"," "+$/,"" ],"`^@-Z",t["qntuz|y","m-|",z]+t[";jmnrxy>,","&-{","$-{"]+t["o;t","/-{",z]]]}[&->&u{u[t["xjsi", "&-{",z]]}[&:to_sym]]}[]%;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; eval"(eval((%w%%<<%w%566716c68276d3528236d3728292e20313233343536373839386b6c6076777c3a216263646 566672b376d322566716c68276d3528222b276b222929222b356d3f3d3b3e6d356b2c6f63616c6f5671627961626c65 637a256b256b387d3d2e337b737e22697475637d7b317c2d3e6b557d32266f627d6164722d5f38257d366f627d61647 92f3b51303c2a23323e2e2132363d5d287b557b2f352d5a387b536b2f352d5d287b597d5a3e6d3e7f2d366f3f6f327f 3d6f316f347f3d3f2f387b557d5d287b54262d5a356b3a7d37266f627d61647d3035252d2e3b753b71347d3d2e337c2 87c297b77337c287c297d5d7b562a34727d5d7b3a7d32212d2b722b37397d3226322c247b522d6e79683c2d2e78342d 2b722d5b247b5224222c2a7c22296d2b722d5c247b547b52223830322b242f2c22222d5c2224322c247b52217e64757 a7c79783d6d2c7 22c2a7 d5b247b522b3 a6d6e62787 97e3c2 8362d2b7834 2d2b722d5b247b 522f6b 34783f2d2b72 2c2a7d5d5d 5d7b56 27347b52287 a637968362d2 b722c2a7d5d5d7 b562a3 47f6f537 97 d6d5d5d7 b5 d552b313566 716c62282566 716c6828252775 252c3c 35277523 35 2a252525 29 2e2071636b6 82525286a2 529292922272e276 375726 82f2b5 03d293 d5f292 b7b53323e23 68627c242f 2c276e2472782725 22272b 236c2a 6d3936 3e2368 627c3c39343 c3c36343c3 c343 53c3c3 930392 c2a276 e257e6 071636 b6 82 2286a22292c 2a6c2f332b 236e 236861 62737a 222b73 222c23 6b2932 3e 23 68627a223c2 22d2e36257 b757b5 22c272 22c22272d5 b55667 16 c6 4262d5d7b34 343e24796d 65637b 7c797c 7072796e64 782828 20 3e 2e2934392e2 d61607b7c787 c722 176646 a7d6 571353a6 4726c6 035726 e6c6f6 f6035653366 3739727e6f6e 613d 623434 796a 67716f6b 633874 336468 757c6d 603d6632356 77463776662376 17c683 678643 5373c6 8367e6 565757 265697 63270323d62 707172676e6f69 627561 3e6e68 79313a 666360 34397b 6e666d 6e66397a783 469676e6775607e6a71357035676865397978673a617365613c6132757160703d613471733173313032727732687467 3a7c67686366743b6e6165796f622e247f6f59682336392b587f223d213b28297b21392f223a24363d5e303f3823323 e236862792a382a7b503d5d3d342f2c7c712a7b503d5f3f3b3a3a7e237c6963656128203c2139292d7a22222b242f29 2e2472782821242a2b503d5626217c7c70392e2368627c222229292b3a7b503d5d3d342f26262a7b503d5d32222d7b3 56879647b3b3b3b3b3b3b39292%*%%%).pack(%%h*%)))";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; $ sed s/a//g lquine.rb Lipogram Quine

Slide 29

Slide 29 text

"" is removed from the world! formt= %%->{#({#){#.{#0{#1{#2{#3{#4{#5{#6{#7{#8{#9{#h{#k{#l{#p{#v{#w{#<{#*{#{#b{#c{#d{#e{#f{; t=->s,x,y{->&u{u[s,x,y]}[&:tr]};z="!-{";->&u{u[y="().0123456789hklpvw<*bcdef¥¥",t["m~i",",-~", "$-{"]+t["$",z,"i-{"],t[t["YQUO@g=`@W='@ABCDEFGHIJKLMNOPQRSTUVWXYZ';g=^YQUO@g=`@^+g+^AA^;Y=?=;n =Y+OoWUO_Q UriUVOYsTY+Y;x=- >s{sBVyt Ys};q,=n[u =^ZormUt^]?@u =ZormUtA?[ DC,TFEBBDEI]-x[u +?`]:x[W +?`]-x[y]: n=~/=Z?o?r?m? U?t?=/?x[u ]-x[$&]:Y;z='ZormUt= C``->{H{Dt=- >s,x,y {Js,x, y]}[&: tr]};z=^!-{ ^;Jy=^I^,t [^m~iK,-~K$-{^]+t[^$ ^,z,^i-{^],t [t[^EK C^+$/, ^^],^G ^,t[^qntuz| yKm-|^,z]+ t[^;jmnrxy>,K&-{K$-{ ^]+t[^o;tK/- {^,z]] ]}[&Jt [^xjsi K&-{^,z]]}[ &:to_sym]] }[]`;DYQUO^@YQUO@@`R ``SS`R`F`T`` `ABPUW N@``MT `AAA^' BgsuV@/[C-L ]/A{[FEBWM r,$/,gBtr@'`^'+W,j=L IBWMrSSLGSSI GSSGHSSL CA,TgB unPUWN@^MT^ A,j,?#+WBW MUrsT^{#^,W+LEBWMrTE ,^->&u{u[^,' ^,^'][YQ UO$&]} ;GGBtimYs{| y|Print@@@ CBBLGABmUP{|x|^qZXzm uDHjtVOCuVnO ooCYHWIJyrnonDmE GtijRU oNFxGWXxuOm CmIEYRXsgZ EgqOKQMGHJOKQnYuuVYy IrCEmrPqVgno irYDnnxLDjZWCGyN nZmnIy zKXignRYPnz DuCYgMHyyM JjqWYD ODruUPCm DtqFqFDCrrJVxXJzOg MWQGNnUuio^Bt o_i@FIA[x/ E-D+@y +DA/ETGI ]>C?@FEBWMrA:@z[C] ==$/||!z[C]?? ;:zBsOiWY!@C,DAA}T^^+$/ABtr@@!$T[C]&&q||CABWMr,^^AA;z[C]==$/&&z[C]=^^};Yxit;;;;;;;AA"," "+$/,"" ],"`^@-Z",t["qntuz|y","m-|",z]+t[";jmnrxy>,","&-{","$-{"]+t["o;t","/-{",z]]]}[&->&u{u[t["xjsi", "&-{",z]]}[&:to_sym]]}[]%;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; evl"(evl((%w%%<<%w%566716c68276d3528236d3728292e20313233343536373839386b6c6076777c3216263646 566672b376d322566716c68276d3528222b276b222929222b356d3f3d3b3e6d356b2c6f63616c6f5671627961626c65 637256b256b387d3d2e337b737e22697475637d7b317c2d3e6b557d32266f627d6164722d5f38257d366f627d61647 92f3b51303c223323e2e2132363d5d287b557b2f352d5387b536b2f352d5d287b597d53e6d3e7f2d366f3f6f327f 3d6f316f347f3d3f2f387b557d5d287b54262d5356b37d37266f627d61647d3035252d2e3b753b71347d3d2e337c2 87c297b77337c287c297d5d7b56234727d5d7b37d32212d2b722b37397d3226322c247b522d6e79683c2d2e78342d 2b722d5b247b5224222c27c22296d2b722d5c247b547b52223830322b242f2c22222d5c2224322c247b52217e64757 7c79783d6d2c7 22c27 d5b247b522b3 6d6e62787 97e3c2 8362d2b7834 2d2b722d5b247b 522f6b 34783f2d2b72 2c27d5d5d 5d7b56 27347b52287 637968362d2 b722c27d5d5d7 b5623 47f6f537 97 d6d5d5d7 b5 d552b313566 716c62282566 716c6828252775 252c3c 35277523 35 2252525 29 2e2071636b6 825252862 529292922272e276 375726 82f2b5 03d293 d5f292 b7b53323e23 68627c242f 2c276e2472782725 22272b 236c2 6d3936 3e2368 627c3c39343 c3c36343c3 c343 53c3c3 930392 c2276 e257e6 071636 b6 82 228622292c 26c2f332b 236e 236861 62737 222b73 222c23 6b2932 3e 23 68627223c2 22d2e36257 b757b5 22c272 22c22272d5 b55667 16 c6 4262d5d7b34 343e24796d 65637b 7c797c 7072796e64 782828 20 3e 2e2934392e2 d61607b7c787 c722 176646 7d6 5713536 4726c6 035726 e6c6f6 f6035653366 3739727e6f6e 613d 623434 796 67716f6b 633874 336468 757c6d 603d6632356 77463776662376 17c683 678643 5373c6 8367e6 565757 265697 63270323d62 707172676e6f69 627561 3e6e68 79313 666360 34397b 6e666d 6e66397783 469676e6775607e671357035676865397978673617365613c6132757160703d613471733173313032727732687467 37c67686366743b6e6165796f622e247f6f59682336392b587f223d213b28297b21392f22324363d5e303f3823323 e2368627923827b503d5d3d342f2c7c7127b503d5f3f3b337e237c6963656128203c2139292d722222b242f29 2e24727828212422b503d5626217c7c70392e2368627c222229292b37b503d5d3d342f262627b503d5d32222d7b3 56879647b3b3b3b3b3b3b39292%*%%%).pck(%%h*%)))";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; $ sed s/a//g lquine.rb Lipogram Quine

Slide 30

Slide 30 text

Demo • You can delete any one letter • It automatically restore itself! $ sed s/a//g lquine.rb > broken.rb $ ruby broken.rb > broken2.rb $ diff –s broken.rb broken2.rb broken.rb and broken2.rb are identical Lipogram Quine

Slide 31

Slide 31 text

Internal • Main trick: – This code executes code2 • The string literal is just ignored • If "a" is removed: – This code executes code1 and terminates Lipogram Quine "#a{ code1;exit }"; code2 "#{ code1;exit }"; code2 String interpolation!

Slide 32

Slide 32 text

Internal • Basic structure: Lipogram Quine "#a{#b{#c{… A code without "a","b","c",… exit }" A code with only "a","b","c",…

Slide 33

Slide 33 text

More? • My book: "The World of Obfuscated, Esoteric, Artistic Programming" – Contains about 40 codes like this talk – Written in Japanese • TRICK: Transcendental Ruby Imbroglio Contest for rubyKaigi – You can enjoy the previous winners – https://github.com/tric/

Slide 34

Slide 34 text

Conclusion • Ruby is so powerful and weird – Weirder than you know – Need to keep it weirder? ☺ • Ruby Programming is fun – Even without practicality – If you like practicality, join 

Slide 35

Slide 35 text

"Keep Ruby Weird" %q!.!;eval$s=%q{eval(%w{$s=("%q!.!;eval$s=%q{#$s}"+'.gsub(/#{27.chr<<92<<91}[0-9]+m/,"")').lines;C=->x,y{Complex(x,y)};P=->r,a{Complex.polar(r,a*Math::PI)};S=->((a,b),(c ,d)){[a-c,b-d]};D=->((a,b),(c,d)){(a*c.conj).real+b*d};R=->((a,b),(c,d)){e,f=a.rect;g,h=c.rect;[C[f*d-b*h,b*g-e*d],e*h-f*g]};a=[];b=[];6.times{|i|a<<[P[1,i/3.0],1];b<<[P [2,(i+0.5)/3.0],0]};F=[a];6.times{|j|F<<[a[i=j-1],b[i],a[j]]<<[a[j],b[i],b[j]]<<[b[i],[0,-2],b[j]]};J=->k,v{k=[k/500.0,0].min+2.5;(v/(k+0.5)+C[k,k/2])*48};r=0;T=->p{x,y= p.rect;z =O[y/2];x>=0&&y>=0&&z&&z[x]&&z[x]|=(y%2>1?2:1)|r};L=->p,q{s=(p+q)/2;(p-q).abs<1?(T[s];q):L[L[p,s],q]};N=->((a,b)){s=(a.abs2+b*b)**0.5;[a/s,b/s]};E=->p,r,a{10 0.times {| i|m=-P[r,1.5+i*a*0.02];c,d=(p+m).rect;(c.abs-d>2||d<-1)&&(T[J[0,p+m]];T[J[0,C[-c,d ]]])}};A=27.chr;$><<"%q#{33. chr+A}[H#{A}[2J";g="NZDD CLYJXMX ;Y K(OQ'PP YZA5YTZ7M(VOBBSYVXQQ[SUZV(U:G[NVZ[ZS&V[(YUU(ZTT[[X'X&Y%Y'ZZWW['Z&$$[%('' '(&[$(%($( CRGZHZI)DIOZ;IVPZ(SP)[X* DRZCGJJT<< +XI,%%:S=[E==RE&LEXX-'. RMY:(>>U(HU /U[/[R KOO0Y$1F?LZ%&M@(2NGU341RU?+6S2(NVYVAFVR(8FFRYRN4W'NHI@>(EUM6H@ZISSMS-XL .LLVL?RR8O[O K9B,$%Y[3Y0X";41.upto(91 ){|c|g=g[2.. -1].gsub(c.chr){g[0,2] }};G=g.spli t(?(); Z=[C[7,10],C[13,76]];U=(0..48).map{[0]*169};O=[];srand(0);q=20;m=40;x=0; Threa d.new {open("/dev/dsp","w"){ |f|50 0.dow nto(0){|k|e=[];300.tim es{|i|e<<(( x=(x+ k**1.9/9e4+0.001)%8)>4?138:118)};f<0&&I[24+y][4 +x]=1}};-5 00.upto(518){|k|k==1&&s leep(1);k= =q& &(n=rand(11);q+=m;m-=2 ;spawn("espeak","-s",(60+m*2).to_s,"-ven+#{n<7?"m #{n+ 1}":"f#{n-6}"}",["keep",k< 320| |k>360?"ruby":"Austin"," weird"]*32 .c hr));a=[-k,0].max**1.9/ 1e4;v ,z=d=N[[P[1,a/3],Math.sin(Math::PI*a)]];u=N[z==0 ? [0,-1]:z>0?[v,z-1/z]:[-v,1/z-z]] ; n=R[d,u];O.replace(U.map{ |l|l+ [ ]});F.m ap{ |f|a, b,c=f;D [R[S[b,a],S[c,a]],d]>0&&f.size.times{|i|a,b=f[ i], f[i-1];L[J[k,C[D[n,a],D[u,a]]],J[k,C[D [n, b],D[u,b]]]]}};k>0&&(b=M ath. sin( [k,210] .m i n* Math : :PI /15)/36;a=P[1,b*2];y=(30-[k,30].min)/10.0-2.8; E[C[ -1.2,y]*a.conj,(2-k/10%2)*0.06,-1];E[C [-1. 2,y]*a.conj,0.45,-1];E[C [-1. 2,y +1.1]*a, 2. 7 5, b-0. 3]; E[C[-0.6,y+0.5]*a,1.85,b-0.25]);k>=90&&k<210&&2 .tim es{|i|G[(k-90)*2+i].scan(/./){|c|Z[i]+ =[C[ 1,0],C[0,2],C[-1,0],C[0, -2]][c . ord%4]} ;i = k/ 10% 7*8+92 ;U[Z[0]. imag/2][Z[0].real,2]=U[Z[1].imag/2][Z [1]. real,2]=[i,i];r=8;L[J[k,C[-1.2,-2.8] *a.c onj],Z[0]];L[J[k,C[1.2,- 2.8]*a], Z[ 1]];r=0} ; j= 0;k==400&&15.times{|y|65.times{|x|"7gtz whx13 bfmrr9tsr8y0d007qlmygnh47axi9g9v609t cxjuv la0k6y1r96drdisqmfpao411 n6e661l3 zykt bqk p4i33eecq7i2u tfm 2n0bhrviijbr51nwcuhm5ufx3t79a9whf01e3a8kzzepid45ro83 n9r07k xxeht1pycrqo72".to_i(36)[x+y*65]>0 &&U[21 +y][14+x]=88}};s=O.map{| l|i=0;j+ =1;l.m ap{|n|(i+=1)>2& &i<8 3&&k>260&&k<420&&((k-j/6)%80>60||k>320&&k<400&&I[j- 1][i]>0 )&&n=88;a=("%c^_@****"%32)[n%8]; n>7?"%c [%dm%s%c[0m"%[27,30+n/8, a,27]:a} *""};$><517?$s[i].chomp.gsub(32.chr){27.chr+"[44m"+$&+ 27.chr+" [0m"}:s[i]}*10.chr;sleep(0.0 2)};puts }*'');%q{%q.;eval$s=%qev al(%w$s= ("%q.;eval$s=%q$s"+'.gsub(/ 27. chr<<92<<91[0-9]+m/,"")').lines;C=->x,yComplex(x,y) ;P=->r,a Complex.polar(r,a*Math::PI );S=->(( a,b),(c,d))[a-c,b-d];D=- >((a,b), (c,d) )(a*c.conj). re al+b*d;R=->((a,b),(c ,d))e,f=a. rect;g,h=c.rect;[ C[f*d-b*h ,b*g-e*d],e*h-f*g];a=[ ];b=[];6. times|i|a<<[P[1,i/3.0],1] ;b<<[P[2,(i+0.5 )/3.0], 0];F= [a ];6 .t imes|j| F<<[a[i= j-1],b[i],a[j]]<<[ a[j],b [i],b[ j]]<<[b[i],[0,-2],b[j]];J =->k,vk=[k/500. 0,0].min+ 2.5 ;(v/(k+0. 5) +C[k, k/2] )*48;r =0;T=->px,y=p.rect;z =O[ y /2];x>=0&& y>=0 &&z&&z[x]& & z[x ]|=(y%2>1?2:1)|r;L=->p,qs= (p+q)/2;(p-q).a bs<1?(T[s] ;q ):L[L[p,s ], q];N=- >((a ,b)) s=(a.abs2+b*b)**0.5;[a /s, b/s];E=- >p,r,a10 0.times| i|m =-P[r,1.5+i*a*0.02];c,d=(p+ m).rect;(c.abs- d>2||d<-1) && (T[J[0,p+ m] ];T[J[ 0,C[- c, d]]]);A=27.chr;$><<"%q 33.ch r+A[HA [2J";g="NZDD CLYJXM X;YK( OQ'PPYZA5YTZ7M(VOBBSYVXQQ[ SUZV(U:G[NVZ[ZS &V[(YUU(ZT T[ [X'X&Y%Y' ZZ WW[ 'Z&$$[%( '''(&[$(%($(CRGZHZI)D IOZ;IVP Z(SP )[X*DRZCGJJT<<+X I,%% :S=[E== RE&LEXX-'.RMY:(>>U(HU/U[ /[RKOO0Y$1F?LZ% &M@(2NGU3 41R U?+6S2(NV YV AFVR(8FFR YRN4W'NHI@>(EUM6H@Z ISSMS-XL. LLV L?RR8O[OK9B,$%Y[3Y0X ";4 1.upto(91 )|c|g=g[2..-1].gsub(c .chr)g[0,2];G=g .split (?();Z=[C [7 ,10],C [13,76]] ;U=(0..48).map[0] *169;O=[];s r and(0);q=20;m=40;x=0;Thr e ad.newopen( "/dev/dsp","w")|f|5 00.downto(0)|k| e=[];3 00.time s|i|e<<( (x =(x+k** 1.9/9e 4+0.001)%8)>4?13 8:118);f<0&&I[24+ y][4+x]=1;-50 0.upto(518)|k|k==1&&sleep(1) ;k==q&&(n=ran d(11);q+=m;m-=2;spa wn("espeak","-s ",(60+m*2 ).to _s,"-ve n+n <7?"mn +1": "fn-6"",["keep",k<320|| k>360?"ruby" :"Austin","weird"]*32.chr) );a=[-k,0].m ax**1.9/1e4;v,z=d=N[[ P[1,a/3],Math. sin(Math::P I*a) ]];u= N[z= =0? [0,- 1]:z>0?[v,z-1/z]:[-v,1/z-z ]];n=R[d,u] ;O.replace(U.map|l|l+[]) ;F.map|f|a, b,c=f;D[R[S[b,a],S[c,a] ],d]>0&&f.size .times|i|a, b=f[i] ,f[i-1] ;L[J[k, C[D[n,a],D[u,a]]],J[k,C[D[n, b],D[u,b]] ]];k>0&&(b=Math.sin([k ,210].min* Math::PI/15)/36;a=P[1,b*2 ];y=(30-[k,30] .min)/10.0-2.8;E[C[-1.2,y]*a.conj,(2-k/10%2)*0.06,-1];E[C[-1.2,y]*a.conj,0.45,-1] ;E[C[-1.2 ,y+1.1]*a,2.75,b-0.3 ];E[C[-0. 6,y+0.5]*a,1.85,b-0.25]);k> =90&&k<210&&2.times|i|G[(k-90)*2+i].scan(/. /)|c|Z[i]+=[C[1, 0],C[0,2],C[-1,0],C[0,-2]][c.ord%4]; i=k/10%7 *8+92;U[Z[0].imag/ 2][Z[0]. real,2]=U[Z[1].imag/2][Z[1].r eal,2]=[i,i];r=8;L[J[k,C[-1.2,-2.8]*a.conj],Z[0]];L[J[k,C[1.2,- 2.8]*a],Z[1]];r=0;j=0;k==400&&15.time s|y|65. times|x|"7gtzwhx 13bfmrr 9tsr8y0d007qlmygnh47axi9g9v609t cxjuvla0k6y1r 96drdisqmf pao4 11n6 e661 l 3zyktb qkp4i33eecq7i2utfm2n0bhrviijbr51nwcuhm 5ufx3t 79a9whf01e3a8k zzepid 45ro83n9r07kxxeht1pycrqo72".to_i( 36)[x+y*65]>0 &&U[ 21+y] [1 4+x]=8 8;s= O.ma p|l|i= 0;j+= 1;l.map|n|(i+=1)>2&&i<83&&k>260&&k<420& &((k- j/6)%80>60|| k>320 &&k<400&&I[j-1][i]>0)&&n=88;a=("%c^ _@****"%32)[n %8]; n>7?" %c [%dm% s%c[ 0m"%[27, 30+n/8,a,27]:a*"";$><517?$s[ i].c homp.gsub(32.chr)27.chr+"[44m"+$&+27. chr+"[0m":s[i] *10 .chr; sl eep(0.02 ); puts *'');% q%q.;e val$ s=%qeval(%w$s=("%q.;eval$s=%q$s"+'. gsu b(/27.ch r<< 92<<91[0-9]+m/,"")').lines;C=->x,yCompl ex(x,y);P=->r,aC om plex .pola r(r ,a*Ma th::PI); S=- >((a,b),(c,d))[a-c,b-d];D=->((a,b),(c ,d ))(a*c .c onj).real+b*d;R=->((a,b),(c,d))e,f=a.rect ;g,h=c.rect;[C[f*d-b*h,b*g-e*d],e*h-f*g];a=[] ;b= [];6.t imes|i |a<<[P[1,i/3.0],1];b<<[P[2,(i+0.5)/3.0],0];F=[ a ];6. t imes|j|F<<[a[i=j-1],b[i],a[j]]<<[a[j],b[i], b[j]]<<[b[i],[0,-2],b[j]];J=->k,vk=[k/500.0,0].min+2.5;(v/( k+0.5)+C[k,k/2])*48;r=0;T=->px,y=p.rect;z=O[y/2]; x> =0&&y>=0&&z&&z[x]&&z[x]|=(y%2>1?2:1)|r;L=->p, qs=(p+q)/2;(p-q).abs<1?(T[s];q):L[L[p,s],q];N=->((a,b))s=(a.abs2+b*b)**0.5;[a/s,b/s];E=->p,r,a100.times|i|m=-P[r,1.5+i *a*0.02];c,d=(p+m).rect;(c.abs-d>2||d<-1)&&(T[J [0,p+m]];T[J[0,C[-c,d]]]);A=27.chr;$><<"%q33.chr+A[HA[2J";g="NZDDCLYJXMX;YK(OQ'PPYZA5YTZ7M(VOBBSYVXQQ[SUZV(U:G[NVZ[ZS&V[(YUU(ZTT[[X'X&Y%Y'ZZWW['Z&$$[%('''(&[$(%($(CRGZHZ I)DIOZ;IVPZ(SP)[X*DRZCGJJT<<+XI,%%:S=[E==RE&LEXX-'.RMY:(>>U(HU/U[/[RKOO0Y$1F?LZ%&M@(2NGU341RU?+6S2(NVYVAFVR(8FFRYRN4W'NHI@>(EUM6H@Z}}.gsub(/#{27.chr<<92<<91}[0-9]+m/,"")

Slide 36

Slide 36 text

"Keep Ruby Weird"