狠狠撸

狠狠撸Share a Scribd company logo
@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のソースにパッチ
●   谤耻产测.肠の濒辞补诲冲蹿颈濒别冲颈苍迟别谤苍补濒()
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レベル
 まとめて别苍诲したい
サンプル(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”なしでインデントで
      别苍诲したい
すでにendless rubyが
  あるのでパス
例6




 縦書きで
搁耻产测を书く
サンプル(迟补迟别冲蝉补尘辫濒别.谤产)
    ??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




スペースとタブで
 搁耻产测を书く
サンプル(产濒别补肠丑冲蝉补尘辫濒别.谤产)



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

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

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



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

“ダァシエリイェス!!”で
   搁耻产测を书く
サンプル(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!
终

More Related Content

メタメタプログラミング搁耻产测