From: Masatoshi SEKI Date: 2001-03-25T09:31:12+09:00 Subject: [ruby-list:28957] Re: erb のバグ (ローカル変数が未定義になってしまう) 咳といいます。 > erbでバグらしき物を発見したので報告します。 > > 特定の条件でローカル変数が未定義になってしまうようです。 > 以下のスクリプトでエラーが発生しました。 > エラーを特定する為に意味不明なプログラムになっています。 > > ---- > #!/usr/local/bin/ruby > require "erb/erb" # erbを呼び出し > chapter_program_data = <<'EndOfErb' > <% > def prev_next_check(full_file) > file_basename = File.basename(full_file) > file_basename =~ /(\d+)-(\d+)/ > end > prev_next_check("2.txt") > %> > EndOfErb > ["1.txt"].each do |read_file| > file_basename = read_file > erb = ERb.new(chapter_program_data) > result_data_template = erb.result(binding) > end > ---- > > file_basename =~ /(\d+)-(\d+)/ > の行で以下のようなエラーが出ます。 > ---- > /cygdrive/c/usr/local/lib/ruby/site_ruby/1.6/erb/erb.rb:39:in `eval': (eval):4:i > n `prev_next_check': undefined local variable or method `file_basename' for # ject:0xa04a2e8> (NameError) > from /cygdrive/c/usr/local/lib/ruby/site_ruby/1.6/erb/strio.rb:68:in `value' > from /cygdrive/c/usr/local/lib/ruby/site_ruby/1.6/erb/strio.rb:68:in `as_stdout' > from /cygdrive/c/usr/local/lib/ruby/site_ruby/1.6/erb/erb.rb:39:in `result' > from test_make_link.rb:15 > from test_make_link.rb:12:in `each' > from test_make_link.rb:12 > ---- ごめんなさい。なぜRubyがこの様なメッセージを出力するのかちょっと わかりませんでした。 ただ、bindingを指定するならeRubyのソースでメソッド定義しないほうが 良いと思います。 ERb/ERbLightはeRubyソースをRubyスクリプトに変換したものを指定された bindingでevalします。(指定がなければTOPLEVEL_BINDING) # 詳しくはerb.rbをごらんください 上記のスクリプトではこういうイメージです。(実際にはもっと複雑) ["1.txt"].each do |read_file| file_basename = read_file def prev_next_check(full_file) file_basename = File.basename(full_file) file_basename =~ /(\d+)-(\d+)/ end prev_next_check("2.txt") end これがどこかのメソッドに入っていたらおそらくエラーですよね。 そういうわけで、 > また似ているのですが以下のようにrequireでメソッド定義を別にするとうまくいきます。 requireまでいかなくても事前にメソッドを定義しておくのをお勧めします。 -------- require "erb/erbl" chapter_program_data = <<'EndOfErb' <% prev_next_check("2.txt") %> EndOfErb def prev_next_check(full_file) file_basename = File.basename(full_file) file_basename =~ /(\d+)-(\d+)/ end ["1.txt"].each do |read_file| file_basename = read_file erb = ERbLight.new(chapter_program_data) result_data_template = erb.result(binding) end