土岐です。

From: Masatoshi SEKI <m_seki / mva.biglobe.ne.jp>
Subject: [ruby-list:13043] Re: Tiny eRuby
Date: Sun, 21 Mar 1999 02:14:06 +0900

> また、erb.rb 本体も if __FILE__ == $0 の部分を少し修正しました。
> ERb クラス自体に変更はありません。

erb.rb と ruby にいくつか問題点を見つけたので報告します。まず、erb.rb 
を引数なしで起動すると ruby がコア・ダンプしてしまいます。

    > ruby erb.rb
    erb.rb:203: [BUG] Segmentation fault
    Abort (core dumped)

ARGV が [nil] になっているとき $<.read を呼んでいるのが原因のようです。

    引数に入力ファイル名がないと ARGV が [nil] になってまう。
        => erb.rb のバグ

    ARGV に文字列以外のオブジェクトが入っていると $<.read で
    コア・ダンプする。
        => ruby のバグ

以下、erb.rb に対するパッチです。

*** erb.rb.seki	Sun Mar 21 12:40:04 1999
--- erb.rb	Sun Mar 21 18:16:28 1999
***************
*** 161,167 ****
        self.unshift "-#{$2}" if $2.size > 0
        "-#{$1}"
      else
!       self.unshift arg
        nil
      end
    end
--- 161,167 ----
        self.unshift "-#{$2}" if $2.size > 0
        "-#{$1}"
      else
!       self.unshift arg if arg
        nil
      end
    end

あともう一つ、erb.rb のタグについてですが、次のようなタグを認識してく
れません。

<%
  def hello
    "Hello"
  end
%>
<%=hello%>

こういう入力を与えると、スクリプトが実行されずにそのまま出力されてしま
います。原因はタグのパターンマッチに '<% ' と ' %>' を使っているためで、
                                        ~      ~
次のようにスペース付けるとタグを認識してくれます。

<% 
  ~             (この行は入力ではない)
  def hello
    "Hello"
  end
 %>
~               (この行は入力ではない)
<%=hello %>
        ~       (この行は入力ではない)

これだと一行のときはいいのですが、複数行に渡ってスクリプトを記述すると
きちょっといやなので、タグのパターンを '<%' と '%>' に変更してちょっと
試してみると、うまくパターンマッチしているように思えます。なにかわけが
あってスペースをつけているのでしょうか、咳さん。一応、タグのパターンを
変更するパッチも付けときます。

*** erb.rb.fixed	Sun Mar 21 18:26:15 1999
--- erb.rb	Sun Mar 21 18:27:31 1999
***************
*** 63,69 ****
    def pre_compile(s)
      list = []
      s.each_line do |line|
!       line.gsub!(/(<%#)|(<%=)|(<% )|( %>)/) do |m|
        "\n#{m}\n"
        end
        list += line.split("\n")
--- 63,69 ----
    def pre_compile(s)
      list = []
      s.each_line do |line|
!       line.gsub!(/(<%#)|(<%=)|(<%)|(%>)/) do |m|
        "\n#{m}\n"
        end
        list += line.split("\n")
***************
*** 74,80 ****
      # print に置換
      list = @print.gsub(list) {
        v = @print.matching_data[1].join
!       ['<% ', "print (#{v})", ' %>']
      }
    end
    module_function :pre_compile
--- 74,80 ----
      # print に置換
      list = @print.gsub(list) {
        v = @print.matching_data[1].join
!       ['<%', "print (#{v})", '%>']
      }
    end
    module_function :pre_compile
***************
*** 110,121 ****
  
    def setup_compiler
      first = ARegexpFirst.new
!     stag = ARegexpEq.new('<% ')
!     etag = ARegexpEq.new(' %>')
      commenttag = ARegexpEq.new('<%#')
      printtag = ARegexpEq.new('<%=')
      any = ARegexpAny.new.repeat(0, nil).greedy(false)
!     notstag = ARegexpEq.new('<% ').negate.repeat(0, nil).greedy(true)
      @head = ARegexp.new([first, notstag]);
      @comment = ARegexp.new([commenttag, any, etag])
      @print = ARegexp.new([printtag, any, etag])
--- 110,121 ----
  
    def setup_compiler
      first = ARegexpFirst.new
!     stag = ARegexpEq.new('<%')
!     etag = ARegexpEq.new('%>')
      commenttag = ARegexpEq.new('<%#')
      printtag = ARegexpEq.new('<%=')
      any = ARegexpAny.new.repeat(0, nil).greedy(false)
!     notstag = ARegexpEq.new('<%').negate.repeat(0, nil).greedy(true)
      @head = ARegexp.new([first, notstag]);
      @comment = ARegexp.new([commenttag, any, etag])
      @print = ARegexp.new([printtag, any, etag])

----------------------------------------------------------------------------
土岐 仁謙	神戸大学物理高エネ研 M1
URL: http://www3.phys.sci.kobe-u.ac.jp/~toki/index.html
PGP fingerprint = D0 A8 90 AB 73 F8 34 FE  CE CA DB BF 01 30 C0 35