2011年5月23日

[ruby-list:48093] eRuby文法の基礎

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 <moonwolf@xxxxx>

--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=

投稿者 xml-rpc : 2011年5月23日 03:00
役に立ちました?:
過去のフィードバック 平均:(0) 総合:(0) 投票回数:(0)
本記事へのTrackback: http://hoop.euqset.org/blog/mt-tb2006.cgi/103937
トラックバック
コメント
コメントする




画像の中に見える文字を入力してください。