From: Nobuyoshi Nakada Date: 2008-02-04T10:09:21+09:00 Subject: [ruby-dev:33586] Re: performance improvement of DelegateClass (was cgi.rb再構築案) なかだです。 At Mon, 4 Feb 2008 04:40:16 +0900, Makoto Kuwata wrote in [ruby-dev:33580]: > (3) CGI::Cookie class が DelegateClass(Array) を使っているせいで、 > require 'cgi' にすごく時間がかかる (ruby の起動より時間がかかる)。 > (時間がかかるのは CGI::HtmlExtention まわりのせいではない) > → 解決策: DelegateClass(Array) を使わないように書き換える cgi.rbとは別に、これも改善するほうがいいでしょう。原因は、細かく module_evalを繰り返すことにあるようです。 メソッドとして正しい識別子か調べるメソッドというものを用意したほ うが簡単かも。 Index: lib/delegate.rb =================================================================== --- lib/delegate.rb (revision 15366) +++ lib/delegate.rb (working copy) @@ -143,5 +143,5 @@ class Delegator end rescue Exception - $@.delete_if{|s| /^#{__FILE__}:\d+:in `method_missing'$/ =~ s} #` + $@.delete_if{|s| %r"\A#{__FILE__}:\d+:in `method_missing'\z"o =~ s} ::Kernel::raise end @@ -279,7 +279,11 @@ def DelegateClass(superclass) end } - for method in methods - begin - klass.module_eval <<-EOS, __FILE__, __LINE__+1 + src = [] + line = __LINE__+3 + if method = methods.find {|m| %r"\A(?:(?!\d)\w+[=!?]?|[-+]@?|\*{1,2}|[/\|&^]|<(?:<|=>?)|>[>=]|~|=(?:~|==?)|![~=]?|\[\]=?)\z" !~ m} + raise NameError, "invalid identifier %s" % method, caller(0) + end + methods.each do |method| + src << <<-EOS def #{method}(*args, &block) begin @@ -289,9 +293,7 @@ def DelegateClass(superclass) end end - EOS - rescue SyntaxError - raise NameError, "invalid identifier %s" % method, caller(3) - end + EOS end + klass.module_eval(src.join, __FILE__, line) return klass end -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦