From: MoonWolf Date: 2011-05-23T03:00:39+09:00 Subject: [ruby-list:48093] eRuby文法の基礎 --JsvMail_Part.JxXMITYFprLhZktEd89Wr09g15 Content-Type: text/plain; charset=ISO-2022-JP Content-Transfer-Encoding: 7bit MoonWolfです。 もうあまりRubyに深入りするつもりはなかったのですが、思いついてしまって 結果も出たので発表します。 eRuby文法の基本的なルールについて、ちょっと考えてみました。 これであっていると思うので実装したeRuby.rbを添付します。 テスト入力と出力を書きます。 ・都合上、改行コードのない入力をテストしてませんが、たぶん大丈夫です。 ・正規表現を使うので文字コードに少し依存します。 ・printメソッドの定義や、文末のセミコロンは省略しています。 ・^Dは入力終了を意味します。^Dより前が入力、後が出力です。 -------------------------------------------------- $ ruby eRuby.rb 123 ^D print("123\n") -------------------------------------------------- $ ruby eRuby.rb abc <%="def"%> ghi ^D print("abc ") print("def") print(" ghi\n") -------------------------------------------------- $ ruby eRuby.rb result: <%=func(param1,param2)%> ^D print("result: ") print(func(param1,param2)) print("\n") -------------------------------------------------- $ ruby eRuby.rb abc<% code %>def ^D print("abc") code print("def\n") -------------------------------------------------- 結論: eRubyの定義は50行程度で書ける。 解説: ・<%=〜%>と<%〜%>しか定義らしいものは無い。 ・eRuby文法はテキストを出力するRubyスクリプトの別表現でしかない。 ・eRubyソースの改行の意味は特にない。解釈するのはRuby処理系の問題 ・インデントの削除や改行の削除などのトリム動作はeRubyの定義にはない。 ・エスケープというものがない。 ・コメントの解釈も処理系の解釈に依存する。 ・文法として間違ったRubyコードが入ってもコンパイルはできるが実行できない。 eRuby処理系の実装者への助言: ・この定義だけで実用的で万能なテンプレートを書くのは困難です。 ・最低限エスケープについての文法の拡張が必要でしょう。 ・コメントアウト機能があったほうがいい。 ・出力を全く行わないeRubyスクリプトも存在する。 ・空のeRubyソースはコードも出力されず、まったく処理を行わない。 最後に: これはeruby,ERb,ErubisといったeRuby処理系が間違っているというための文章ではありません。 eRubyの定義が少なすぎるからeRuby2とでもいうべきものを新しく定義したほうがいいのではないか、 ということに気がついたよ、というだけです。 -- MoonWolf --JsvMail_Part.JxXMITYFprLhZktEd89Wr09g15 Content-Type: text/x-ruby; charset=us-ascii; name="eRuby.rb" Content-Disposition: attachment; filename="eRuby.rb" Content-Transfer-Encoding: Quoted-Printable #!/usr/bin/ruby=0A= def eRuby(eruby_source)=0A= source =3D eruby_source=0A= ruby =3D ''=0A= loop do=0A= break if source.empty?=0A= =0A= if source=3D~/<%=3D/m=0A= text =3D $`=0A= if text !=3D ""=0A= ruby << "print(#{text.dump})\n"=0A= end=0A= source =3D $'=0A= if source=3D~/%>/m=0A= code =3D $`=0A= if code !=3D ""=0A= ruby << "print(#{code})\n"=0A= end=0A= source=3D$'=0A= next=0A= else=0A= raise "<%=3D unmatch error"=0A= end=0A= end=0A= =0A= if source=3D~/<%/m=0A= text =3D $`=0A= if text !=3D ""=0A= ruby << "print(#{text.dump})\n"=0A= end=0A= source =3D $'=0A= if source=3D~/%>/m=0A= code =3D $`=0A= if code !=3D ""=0A= ruby << code << "\n"=0A= end=0A= source=3D$'=0A= next=0A= else=0A= raise "<% unmatch error"=0A= end=0A= end=0A= =0A= ruby << "print(#{source.dump})\n"=0A= break=0A= end=0A= ruby=0A= end=0A= =0A= if $0=3D=3D__FILE__=0A= print eRuby(STDIN.read)=0A= end=0A= --JsvMail_Part.JxXMITYFprLhZktEd89Wr09g15--