Your SlideShare is downloading. ×
メタメタプログラミングRuby
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

メタメタプログラミングRuby

855
views

Published on

NOTE: These are joke programs

NOTE: These are joke programs

Published in: Art & Photos

0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
855
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
2
Comments
0
Likes
1
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. @emasaka
  • 2. 自己紹介● @emasaka● 本名:高橋正和● 40代 フリーター● ブログ 「本を読む」http://emasaka.blog65.fc2.com/● 代表作:Bash on Rails
  • 3. 近況
  • 4. nagaino作りました● 複数の短縮URLを1リクエストで多段展開する Web APIサービス http://nagaino.herokuapp.com/
  • 5. 今日の話
  • 6. Perl
  • 7. Perlのソースフィルタ● ソースを読み込んでからパースするまでの間 に、スクリプトからソースを直接いじれる
  • 8. Filter::SQL● Perlのソース中にインラインでSQL文を埋め 込む● 奥一穂氏作
  • 9. どっちかというとAcme(ネタ系)モジュールで 使われる
  • 10. Acme::Bleach● 自分を読みんでいるソースファイルを書き換え て、空白とタブだけにしてしまう● (でも実行できる)
  • 11. Acme::Brainfuck● Perlのソース中にインラインでBrainf*ckを埋 め込む
  • 12. Acme::W● Perlの識別子を草だらけにする ● print → WWwwWW
  • 13. Acme::Metification● ソース中に“meta 2, 5”と書くと、その行が、 2〜5行目の内容に置きかわる ● 指定範囲に自分が入っていると無限再帰● “recursemeta depth => 10, 2, 5”と書くと、 10レベルまで再帰
  • 14. Rubyで(超簡易版)ソースフィルタ
  • 15. Rubyのソースにパッチ● ruby.cのload_file_internal()
  • 16. diff ­up ruby­1.9.2­p290/ruby.c filter­ruby­1.9.2­p290/ruby.c­­­ ruby­1.9.2­p290/ruby.c      2010­12­23 19:49:13.000000000 +0900+++ filter­ruby­1.9.2­p290/ruby.c       2011­10­28 21:50:44.452623054 +0900@@ ­1618,7 +1618,16 @@ load_file_internal(VALUE arg)        return (VALUE)rb_parser_compile_string(parser, fname, f, line_start);     }     rb_funcall(f, set_encoding, 2, rb_enc_from_encoding(enc), rb_str_new_cstr("­"));­    tree = rb_parser_compile_file(parser, fname, f, line_start);+    {+       VALUE source_filter = rb_intern("source_filter");+       if (rb_obj_respond_to(rb_cObject, source_filter, 1)) {+           VALUE s1 = rb_funcall(f, rb_intern("read"), 0);+           VALUE s2 = rb_funcall(rb_mKernel, source_filter, 1, s1);+           tree = rb_parser_compile_string(parser, fname, s2, line_start);+       } else {+           tree = rb_parser_compile_file(parser, fname, f, line_start);+       }+    }     rb_funcall(f, set_encoding, 1, rb_parser_encoding(parser));     if (script && tree && rb_parser_end_seen_p(parser)) {        rb_define_global_const("DATA", f);
  • 17. 内容● source_filterメソッドが定義されていれば ● ファイルの内容をStringに読み込む ● source_filterに通す ● 結果をパース● 定義されていなければいつも通り
  • 18. 利用例
  • 19. 例1「Rubyのメソッド呼び出しが“.”なのは直感に 反する。 “->”に」
  • 20. フィルタ(arrow.rb)def source_filter(str)  str.gsub(/­>/, .)end
  • 21. サンプル(arrow_sample.rb)[3, 5, 7]­>map {|i| i + 2 }­>each do |i|  puts i­>to_send
  • 22. 実行$ ruby ­rarrow arrow_sample.rb579 コマンドライン で直接指定
  • 23. 例2:さらに● “$”“{”を無視● “}”を“end”に● “function”を“def”に● “this”を“self”に
  • 24. フィルタ(arrow2.rb)def source_filter(str)  str.gsub(/­>/, .).gsub(/}/, end).    gsub(/function/, def).    gsub(/this/, self).    delete(${)end
  • 25. サンプル(arrow2_sample.rb)class Hoge {  function foo() {    puts($this­>class());    return $this;  }}Hoge­>new­>foo();
  • 26. 実行$ ruby ­rarrow2 arrow2_sample.rbHoge
  • 27. 例3「Rubyはrequireとinclude が混乱する」
  • 28. フィルタ(include.rb)def source_filter(str)  str.gsub(/^s*#s*includes+<(.[^>]*)>$/,           require "1" )end
  • 29. サンプル(include_sample.rb)#include <uri>u = URI.parse("http://example.com:80/hoge?fuga#foo")p u
  • 30. 実行$ ruby ­rinclude include_sample.rb#<URI::HTTP:0x8463c84 URL:http://example.com/hoge?fuga#foo>
  • 31. 例4“ennnnnd”で5レベル まとめてendしたい
  • 32. サンプル(ennd_sample.rb)module MyModule  class MyClass    def my_method      10.times do |i|        if (i % 2) == 0          puts even        else          puts odd        ennnnndMyModule::MyClass.new.my_method
  • 33. フィルタ(ennd.rb)def source_filter(str)  str.gsub(/e(n{2,})d/) do    Array.new($1.length, end).join(;)  endend
  • 34. 実行$ ruby ­rennd ennd_sample.rbevenoddevenoddevenoddevenoddevenodd
  • 35. 例5“end”なしでインデントで endしたい
  • 36. すでにendless rubyが あるのでパス
  • 37. 例6 縦書きでRubyを書く
  • 38. サンプル(tate_sample.rb)   e           (   n           1   d  e     i  .      n     f  .      d  p     2         u  (  0         t  i  )         s     .            %  e         i     a            2  c            )  h                            =  d            =  o                            0  |               i               |
  • 39. フィルタ(tate.rb)def source_filter(str)  str.split(/n/).inject([]) {|r, s|    s.each_char.with_index do |c, i|      r[i] = r[i] ? r[i] + c : c    end    r  }.reverse.join("n")end
  • 40. 実行$ ruby ­rtate tate_sample.rb2468101214161820
  • 41. 例7スペースとタブで Rubyを書く
  • 42. サンプル(bleach_sample.rb) 見えません
  • 43. フィルタ(bleach.rb)def source_filter(str)  [str.delete("^ t").   tr(" t", 01) ].pack(b*)end
  • 44. 実行$ ruby ­rbleach bleach_sample.rbHello, World!
  • 45. 例8 見えないとつまらないので“ダァシエリイェス!!”で Rubyを書く
  • 46. サンプル(kq_sample.rb)ダァダァダァダァシエリイェス!!シエリイェス!!シエリイェス!!ダァシエリイェス!!ダァシエリイェス!!ダァシエリイェス!!シエリイェス!!シエリイェス!!ダァダァダァシエリイェス!!ダァシエリイェス!!シエリイェス!!シエリイェス!!ダァシエリイェス!!シエリイェス!!ダァダァシエリイェス!!シエリイェス!!シエリイェス!!ダァダァダァダァダァダァシエリイェス!!ダァダァシエリイェス!!シエリイェス!!シエリイェス!!ダァダァシエリイェス!!ダァダァダァダァダァシエリイェス!!ダァダァシエリイェス!!ダァシエリイェス!!ダァシエリイェス!!ダァダァシエリイェス!!シエリイェス!!ダァダァダァシエリイェス!!シエリイェス!!ダァシエリイェス!!シエリイェス!!ダァダァダァシエリイェス!!シエリイェス!!ダァシエリイェス!!シエリイェス!!ダァシエリイェス!!シエリイェス!!シエリイェス!!シエリイェス!!ダァシエリイェス!!シエリイェス!!ダァダァダァシエリイェス!!シエリイェス!!ダァシエリイェス!!ダァダァダァダァダァダァダァシエリイェス!!ダァダァシエリイェス!!シエリイェス!!シエリイェス!!ダァシエリイェス!!ダァシエリイェス!!ダァシエリイェス!!シエリイェス!!シエリイェス!!シエリイェス!!ダァシエリイェス!!シエリイェス!!ダァダァシエリイェス!!ダァダァシエリイェス!!シエリイェス!!シエリイェス!!ダァダァダァシエリイェス!!シエリイェス!!ダァシエリイェス!!シエリイェス!!ダァダァダァシエリイェス!!ダァダァシエリイェス!!シエリイェス!!ダァシエリイェス!!ダァダァダァダァシエリイェス!!ダァダァシエリイェス!!シエリイェス!!シエリイェス!!ダァダァシエリイェス!!ダァダァダァシエリイェス!!ダァシエリイェス!!ダァダァダァダァ
  • 47. フィルタ(kq.rb)# ­*­ coding: utf­8 ­*­def source_filter(str)  [str.force_encoding(Encoding::UTF_8).   scan(/ダァ|シエリイェス!!/).   map {|s| s == ダァ ? 0 : 1 }.   join() ].pack(b*)end
  • 48. 実行$ ruby ­rkq kq_sample.rbHello, World!
  • 49.

×