SlideShare una empresa de Scribd logo
1 de 49
Descargar para leer sin conexión
@emasaka
自己紹介
●   @emasaka
●   本名:高橋正和
●   40代 フリーター
●   ブログ
    「本を読む」http://emasaka.blog65.fc2.com/
●   代表作:Bash on Rails
近況
nagaino作りました
●   複数の短縮URLを1リクエストで多段展開する
    Web APIサービス

                    http://nagaino.herokuapp.com/
今日の話
Perl
Perlのソースフィルタ
●   ソースを読み込んでからパースするまでの間
    に、スクリプトからソースを直接いじれる
Filter::SQL
●   Perlのソース中にインラインでSQL文を埋め
    込む
●   奥一穂氏作
どっちかというとAcme
(ネタ系)モジュールで
    使われる
Acme::Bleach
●   自分を読みんでいるソースファイルを書き換え
    て、空白とタブだけにしてしまう
●   (でも実行できる)
Acme::Brainfuck
●   Perlのソース中にインラインでBrainf*ckを埋
    め込む
Acme::W
●   Perlの識別子を草だらけにする
    ●   print → WWwwWW
Acme::Metification
●   ソース中に“meta 2, 5”と書くと、その行が、
    2〜5行目の内容に置きかわる
    ●   指定範囲に自分が入っていると無限再帰
●   “recursemeta depth => 10, 2, 5”と書くと、
    10レベルまで再帰
Rubyで(超簡易版)
ソースフィルタ
Rubyのソースにパッチ
●   ruby.cのload_file_internal()
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);
内容
●   source_filterメソッドが定義されていれば
    ●   ファイルの内容をStringに読み込む
    ●   source_filterに通す
    ●   結果をパース
●   定義されていなければいつも通り
利用例
例1

「Rubyのメソッド呼び
出しが“.”なのは直感に
     反する。
    “->”に」
フィルタ(arrow.rb)

def source_filter(str)
  str.gsub(/­>/, '.')
end
サンプル(arrow_sample.rb)

[3, 5, 7]­>map {|i| i + 2 }­>each do |i|
  puts i­>to_s
end
実行

$ ruby ­rarrow arrow_sample.rb
5
7
9
              コマンドライン
              で直接指定
例2:さらに
●   “$”“{”を無視
●   “}”を“end”に
●   “function”を“def”に
●   “this”を“self”に
フィルタ(arrow2.rb)

def source_filter(str)
  str.gsub(/­>/, '.').gsub(/}/, 'end').
    gsub(/function/, 'def').
    gsub(/this/, 'self').
    delete('${')
end
サンプル(arrow2_sample.rb)

class Hoge {
  function foo() {
    puts($this­>class());
    return $this;
  }
}

Hoge­>new­>foo();
実行

$ ruby ­rarrow2 arrow2_sample.rb
Hoge
例3




「Rubyはrequireとinclude
     が混乱する」
フィルタ(include.rb)

def source_filter(str)
  str.gsub(/^s*#s*includes+<(.[^>]*)>$/,
           'require "1"' )
end
サンプル(include_sample.rb)

#include <uri>

u = URI.parse("http://example.com:80/hoge?
fuga#foo")
p u
実行

$ ruby ­rinclude include_sample.rb
#<URI::HTTP:0x8463c84 
URL:http://example.com/hoge?fuga#foo>
例4



“ennnnnd”で5レベル
 まとめてendしたい
サンプル(ennd_sample.rb)

module MyModule
  class MyClass
    def my_method
      10.times do |i|
        if (i % 2) == 0
          puts 'even'
        else
          puts 'odd'
        ennnnnd

MyModule::MyClass.new.my_method
フィルタ(ennd.rb)

def source_filter(str)
  str.gsub(/e(n{2,})d/) do
    Array.new($1.length, 'end').join(';')
  end
end
実行

$ ruby ­rennd ennd_sample.rb
even
odd
even
odd
even
odd
even
odd
even
odd
例5




“end”なしでインデントで
      endしたい
すでにendless rubyが
  あるのでパス
例6




 縦書きで
Rubyを書く
サンプル(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
                  |
フィルタ(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
実行

$ ruby ­rtate tate_sample.rb
2
4
6
8
10
12
14
16
18
20
例7




スペースとタブで
 Rubyを書く
サンプル(bleach_sample.rb)



    見えません
フィルタ(bleach.rb)

def source_filter(str)
  [str.delete("^ t").
   tr(" t", '01') ].pack('b*')
end
実行

$ ruby ­rbleach bleach_sample.rb
Hello, World!
例8



  見えないとつまらないので

“ダァシエリイェス!!”で
   Rubyを書く
サンプル(kq_sample.rb)
ダァダァダァダァシエリイェス!!シエリイェス!!
シエリイェス!!ダァシエリイェス!!ダァシエリイェス!!ダァ
シエリイェス!!シエリイェス!!シエリイェス!!ダァダァダァ
シエリイェス!!ダァシエリイェス!!シエリイェス!!シエリイェス!!ダァ
シエリイェス!!シエリイェス!!ダァダァシエリイェス!!シエリイェス!!
シエリイェス!!ダァダァダァダァダァ
ダァシエリイェス!!ダァダァシエリイェス!!シエリイェス!!
シエリイェス!!ダァダァシエリイェス!!ダァダァ
ダァダァダァシエリイェス!!ダァダァ
シエリイェス!!ダァシエリイェス!!ダァシエリイェス!!ダァ
ダァシエリイェス!!シエリイェス!!ダァダァダァ
シエリイェス!!シエリイェス!!ダァシエリイェス!!シエリイェス!!ダァ
ダァダァシエリイェス!!シエリイェス!!ダァシエリイェス!!
シエリイェス!!ダァシエリイェス!!シエリイェス!!シエリイェス!!シエリイェス!!
ダァシエリイェス!!シエリイェス!!ダァダァダァ
シエリイェス!!シエリイェス!!ダァシエリイェス!!ダァダァ
ダァダァダァダァダァシエリイェス!!
ダァダァシエリイェス!!シエリイェス!!シエリイェス!!ダァ
シエリイェス!!ダァシエリイェス!!ダァシエリイェス!!シエリイェス!!
シエリイェス!!シエリイェス!!ダァシエリイェス!!シエリイェス!!ダァ
ダァシエリイェス!!ダァダァシエリイェス!!シエリイェス!!
シエリイェス!!ダァダァダァシエリイェス!!シエリイェス!!
ダァシエリイェス!!シエリイェス!!ダァダァダァ
シエリイェス!!ダァダァシエリイェス!!シエリイェス!!ダァ
シエリイェス!!ダァダァダァダァシエリイェス!!
ダァダァシエリイェス!!シエリイェス!!シエリイェス!!ダァ
ダァシエリイェス!!ダァダァダァシエリイェス!!
ダァシエリイェス!!ダァダァダァダァ
フィルタ(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
実行

$ ruby ­rkq kq_sample.rb
Hello, World!
終

Más contenido relacionado

La actualidad más candente

Python で munin plugin を書いてみる
Python で munin plugin を書いてみるPython で munin plugin を書いてみる
Python で munin plugin を書いてみるftnk
 
awk v.s. bashどっちが強い?@OSC2011Tokyo
awk v.s. bashどっちが強い?@OSC2011Tokyoawk v.s. bashどっちが強い?@OSC2011Tokyo
awk v.s. bashどっちが強い?@OSC2011TokyoRyuichi Ueda
 
Perlで伝統芸能
Perlで伝統芸能Perlで伝統芸能
Perlで伝統芸能hitode909
 
毎秒2000Requestを捌くPerl製CMSの内部構造(Debianサーバ1台にて)
毎秒2000Requestを捌くPerl製CMSの内部構造(Debianサーバ1台にて)毎秒2000Requestを捌くPerl製CMSの内部構造(Debianサーバ1台にて)
毎秒2000Requestを捌くPerl製CMSの内部構造(Debianサーバ1台にて)nabe-abk
 
実用裏方 Perl 入門
実用裏方 Perl 入門実用裏方 Perl 入門
実用裏方 Perl 入門keroyonn
 
Mojoliciousをウェブ制作現場で使ってみてる
Mojoliciousをウェブ制作現場で使ってみてるMojoliciousをウェブ制作現場で使ってみてる
Mojoliciousをウェブ制作現場で使ってみてるjamadam
 
ゲットーの斜め上をゆくWebアプリケーションフレームワークの開発
ゲットーの斜め上をゆくWebアプリケーションフレームワークの開発ゲットーの斜め上をゆくWebアプリケーションフレームワークの開発
ゲットーの斜め上をゆくWebアプリケーションフレームワークの開発emasaka
 
GNU awk (gawk) を用いた Apache ログ解析方法
GNU awk (gawk) を用いた Apache ログ解析方法GNU awk (gawk) を用いた Apache ログ解析方法
GNU awk (gawk) を用いた Apache ログ解析方法博文 斉藤
 
最新PHP事情 (2000年7月22日,PHPカンファレンス)
最新PHP事情 (2000年7月22日,PHPカンファレンス)最新PHP事情 (2000年7月22日,PHPカンファレンス)
最新PHP事情 (2000年7月22日,PHPカンファレンス)Rui Hirokawa
 
ActiveResourceが面白すぎる件
ActiveResourceが面白すぎる件ActiveResourceが面白すぎる件
ActiveResourceが面白すぎる件Kazuki MATSUMOTO
 
RのffとbigmemoryとRevoScaleRとを比較してみた
RのffとbigmemoryとRevoScaleRとを比較してみたRのffとbigmemoryとRevoScaleRとを比較してみた
RのffとbigmemoryとRevoScaleRとを比較してみたKazuya Wada
 
PHPの今とこれから2021
PHPの今とこれから2021PHPの今とこれから2021
PHPの今とこれから2021Rui Hirokawa
 
Spectacular Future with clojure.spec
Spectacular Future with clojure.specSpectacular Future with clojure.spec
Spectacular Future with clojure.specKent Ohashi
 
最近の PHP の話
最近の PHP の話最近の PHP の話
最近の PHP の話y-uti
 

La actualidad más candente (20)

Python で munin plugin を書いてみる
Python で munin plugin を書いてみるPython で munin plugin を書いてみる
Python で munin plugin を書いてみる
 
awk v.s. bashどっちが強い?@OSC2011Tokyo
awk v.s. bashどっちが強い?@OSC2011Tokyoawk v.s. bashどっちが強い?@OSC2011Tokyo
awk v.s. bashどっちが強い?@OSC2011Tokyo
 
Perlで伝統芸能
Perlで伝統芸能Perlで伝統芸能
Perlで伝統芸能
 
毎秒2000Requestを捌くPerl製CMSの内部構造(Debianサーバ1台にて)
毎秒2000Requestを捌くPerl製CMSの内部構造(Debianサーバ1台にて)毎秒2000Requestを捌くPerl製CMSの内部構造(Debianサーバ1台にて)
毎秒2000Requestを捌くPerl製CMSの内部構造(Debianサーバ1台にて)
 
前期講座09
前期講座09前期講座09
前期講座09
 
Ll xcode
Ll xcodeLl xcode
Ll xcode
 
実用裏方 Perl 入門
実用裏方 Perl 入門実用裏方 Perl 入門
実用裏方 Perl 入門
 
Mojoliciousをウェブ制作現場で使ってみてる
Mojoliciousをウェブ制作現場で使ってみてるMojoliciousをウェブ制作現場で使ってみてる
Mojoliciousをウェブ制作現場で使ってみてる
 
ゲットーの斜め上をゆくWebアプリケーションフレームワークの開発
ゲットーの斜め上をゆくWebアプリケーションフレームワークの開発ゲットーの斜め上をゆくWebアプリケーションフレームワークの開発
ゲットーの斜め上をゆくWebアプリケーションフレームワークの開発
 
GNU awk (gawk) を用いた Apache ログ解析方法
GNU awk (gawk) を用いた Apache ログ解析方法GNU awk (gawk) を用いた Apache ログ解析方法
GNU awk (gawk) を用いた Apache ログ解析方法
 
最新PHP事情 (2000年7月22日,PHPカンファレンス)
最新PHP事情 (2000年7月22日,PHPカンファレンス)最新PHP事情 (2000年7月22日,PHPカンファレンス)
最新PHP事情 (2000年7月22日,PHPカンファレンス)
 
ActiveResourceが面白すぎる件
ActiveResourceが面白すぎる件ActiveResourceが面白すぎる件
ActiveResourceが面白すぎる件
 
RのffとbigmemoryとRevoScaleRとを比較してみた
RのffとbigmemoryとRevoScaleRとを比較してみたRのffとbigmemoryとRevoScaleRとを比較してみた
RのffとbigmemoryとRevoScaleRとを比較してみた
 
Slub data structure
Slub data structureSlub data structure
Slub data structure
 
Teclab3
Teclab3Teclab3
Teclab3
 
PHPの今とこれから2021
PHPの今とこれから2021PHPの今とこれから2021
PHPの今とこれから2021
 
Spectacular Future with clojure.spec
Spectacular Future with clojure.specSpectacular Future with clojure.spec
Spectacular Future with clojure.spec
 
Slub alloc and free
Slub alloc and freeSlub alloc and free
Slub alloc and free
 
最近の PHP の話
最近の PHP の話最近の PHP の話
最近の PHP の話
 
Testman
TestmanTestman
Testman
 

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

20110820 metaprogramming
20110820 metaprogramming20110820 metaprogramming
20110820 metaprogrammingMasanori Kado
 
ffi for rubyists
ffi for rubyistsffi for rubyists
ffi for rubyistsnanki
 
第2回品川Redmine勉強会(日本語全文検索)
第2回品川Redmine勉強会(日本語全文検索)第2回品川Redmine勉強会(日本語全文検索)
第2回品川Redmine勉強会(日本語全文検索)Masanori Machii
 
Php in ruby
Php in rubyPhp in ruby
Php in rubydo_aki
 
Ruby on Rails 入門
Ruby on Rails 入門Ruby on Rails 入門
Ruby on Rails 入門Yasuko Ohba
 
知って得する標準関数の使い方
知って得する標準関数の使い方知って得する標準関数の使い方
知って得する標準関数の使い方Soudai Sone
 
Start!! Ruby
Start!! RubyStart!! Ruby
Start!! Rubymitim
 
Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3Ransui Iso
 
Rails初心者レッスン lesson1 3rd edition
Rails初心者レッスン lesson1 3rd editionRails初心者レッスン lesson1 3rd edition
Rails初心者レッスン lesson1 3rd editionGoh Matsumoto
 
PHP AST 徹底解説
PHP AST 徹底解説PHP AST 徹底解説
PHP AST 徹底解説do_aki
 
Web技術勉強会23回目
Web技術勉強会23回目Web技術勉強会23回目
Web技術勉強会23回目龍一 田中
 
Racc でおてがる構文解析
Racc でおてがる構文解析Racc でおてがる構文解析
Racc でおてがる構文解析morphine57
 
いまさら聞けないRake入門
いまさら聞けないRake入門いまさら聞けないRake入門
いまさら聞けないRake入門Tomoya Kawanishi
 
Ruby Sapporo Night Vol4
Ruby Sapporo Night Vol4Ruby Sapporo Night Vol4
Ruby Sapporo Night Vol4Koji SHIMADA
 
kpfx07 LT ruby-processingでイケメンになりたい
kpfx07 LT ruby-processingでイケメンになりたいkpfx07 LT ruby-processingでイケメンになりたい
kpfx07 LT ruby-processingでイケメンになりたいkoki_h
 

Similar a メタメタプログラミングRuby (20)

20110820 metaprogramming
20110820 metaprogramming20110820 metaprogramming
20110820 metaprogramming
 
ffi for rubyists
ffi for rubyistsffi for rubyists
ffi for rubyists
 
第2回品川Redmine勉強会(日本語全文検索)
第2回品川Redmine勉強会(日本語全文検索)第2回品川Redmine勉強会(日本語全文検索)
第2回品川Redmine勉強会(日本語全文検索)
 
Haikara
HaikaraHaikara
Haikara
 
Php in ruby
Php in rubyPhp in ruby
Php in ruby
 
Ruby on Rails 入門
Ruby on Rails 入門Ruby on Rails 入門
Ruby on Rails 入門
 
知って得する標準関数の使い方
知って得する標準関数の使い方知って得する標準関数の使い方
知って得する標準関数の使い方
 
Start!! Ruby
Start!! RubyStart!! Ruby
Start!! Ruby
 
Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3
 
Rails初心者レッスン lesson1 3rd edition
Rails初心者レッスン lesson1 3rd editionRails初心者レッスン lesson1 3rd edition
Rails初心者レッスン lesson1 3rd edition
 
PHP AST 徹底解説
PHP AST 徹底解説PHP AST 徹底解説
PHP AST 徹底解説
 
Project lambda
Project lambdaProject lambda
Project lambda
 
URLで遊ぼう
URLで遊ぼうURLで遊ぼう
URLで遊ぼう
 
Scala on Hadoop
Scala on HadoopScala on Hadoop
Scala on Hadoop
 
Web技術勉強会23回目
Web技術勉強会23回目Web技術勉強会23回目
Web技術勉強会23回目
 
Racc でおてがる構文解析
Racc でおてがる構文解析Racc でおてがる構文解析
Racc でおてがる構文解析
 
いまさら聞けないRake入門
いまさら聞けないRake入門いまさら聞けないRake入門
いまさら聞けないRake入門
 
Ruby Sapporo Night Vol4
Ruby Sapporo Night Vol4Ruby Sapporo Night Vol4
Ruby Sapporo Night Vol4
 
kpfx07 LT ruby-processingでイケメンになりたい
kpfx07 LT ruby-processingでイケメンになりたいkpfx07 LT ruby-processingでイケメンになりたい
kpfx07 LT ruby-processingでイケメンになりたい
 
Ruby 2.5
Ruby 2.5Ruby 2.5
Ruby 2.5
 

Más de emasaka

ibus-skkをなんとかすっぺ会議
ibus-skkをなんとかすっぺ会議ibus-skkをなんとかすっぺ会議
ibus-skkをなんとかすっぺ会議emasaka
 
濁点の話
濁点の話濁点の話
濁点の話emasaka
 
GoBoLinuxを試した
GoBoLinuxを試したGoBoLinuxを試した
GoBoLinuxを試したemasaka
 
さくらのクラウドでh2oのベンチマーク
さくらのクラウドでh2oのベンチマークさくらのクラウドでh2oのベンチマーク
さくらのクラウドでh2oのベンチマークemasaka
 
みおぽん for CLI
みおぽん for CLIみおぽん for CLI
みおぽん for CLIemasaka
 
GNU make 4.0に何かいる
GNU make 4.0に何かいるGNU make 4.0に何かいる
GNU make 4.0に何かいるemasaka
 
長いの
長いの長いの
長いのemasaka
 
)の品格
)の品格)の品格
)の品格emasaka
 
エコなWebサーバー
エコなWebサーバーエコなWebサーバー
エコなWebサーバーemasaka
 
Bash on Railsの逆襲
Bash on Railsの逆襲Bash on Railsの逆襲
Bash on Railsの逆襲emasaka
 

Más de emasaka (11)

ibus-skkをなんとかすっぺ会議
ibus-skkをなんとかすっぺ会議ibus-skkをなんとかすっぺ会議
ibus-skkをなんとかすっぺ会議
 
濁点の話
濁点の話濁点の話
濁点の話
 
GoBoLinuxを試した
GoBoLinuxを試したGoBoLinuxを試した
GoBoLinuxを試した
 
さくらのクラウドでh2oのベンチマーク
さくらのクラウドでh2oのベンチマークさくらのクラウドでh2oのベンチマーク
さくらのクラウドでh2oのベンチマーク
 
みおぽん for CLI
みおぽん for CLIみおぽん for CLI
みおぽん for CLI
 
GNU make 4.0に何かいる
GNU make 4.0に何かいるGNU make 4.0に何かいる
GNU make 4.0に何かいる
 
長いの
長いの長いの
長いの
 
)の品格
)の品格)の品格
)の品格
 
人力
人力人力
人力
 
エコなWebサーバー
エコなWebサーバーエコなWebサーバー
エコなWebサーバー
 
Bash on Railsの逆襲
Bash on Railsの逆襲Bash on Railsの逆襲
Bash on Railsの逆襲
 

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