Hi.

>I have some code which I wanted to run under the profiler but it's
>raising an error within the profiler code:
>
>c:/ruby/lib/ruby/1.8/profiler.rb:27: undefined method `[]' for
>nil:NilClass (NoMethodError)
>        from c:/ruby/lib/ruby/1.8/profiler.rb:5:in `times'
>        from art.rb:119:in `times'
>        from art.rb:119

This error was reported at [ruby-core:4775], and I posted patch at [ruby-core:4793].
But that patch was slower than original one, so I reimplemented.

Does this patch help you? (I hope calculation is correct)

Index: profiler.rb
===================================================================
RCS file: /src/ruby/lib/profiler.rb,v
retrieving revision 1.1
diff -u -w -b -p -r1.1 profiler.rb
--- profiler.rb	20 Dec 2002 09:00:10 -0000	1.1
+++ profiler.rb	29 Apr 2005 14:51:52 -0000
@@ -1,40 +1,29 @@
 module Profiler__
-  Times = if defined? Process.times then Process else Time end
   # internal values
   @@start = @@stack = @@map = nil
   PROFILE_PROC = proc{|event, file, line, id, binding, klass|
     case event
     when "call", "c-call"
-      now = Float(Times::times[0])
-      @@stack.push [now, 0.0, id]
+      now = Float(Process.times[0])
+      @@stack.push [now, 0.0]
     when "return", "c-return"
-      now = Float(Times::times[0])
-      tick = @@stack.pop
-      name = klass.to_s
-      if name.nil? then name = '' end
-      if klass.kind_of? Class
-	name += "#"
-      else
-	name += "."
-      end
-      name += id.id2name
-      data = @@map[name]
-      unless data
-	data = [0.0, 0.0, 0.0, name]
-	@@map[name] = data
-      end
+      now = Float(Process.times[0])
+      key = [klass, id]
+      if tick = @@stack.pop
+        data = (@@map[key] ||= [0, 0.0, 0.0, key])
       data[0] += 1
       cost = now - tick[0]
       data[1] += cost
       data[2] += cost - tick[1]
-      @@stack[-1][1] += cost
+        @@stack[-1][1] += cost if @@stack[-1]
+      end
     end
   }
 module_function
   def start_profile
-    @@start = Float(Times::times[0])
-    @@stack = [[0, 0, :toplevel], [0, 0, :dummy]]
-    @@map = {"#toplevel" => [1, 0, 0, "#toplevel"]}
+    @@start = Float(Process.times[0])
+    @@stack = []
+    @@map = {}
     set_trace_func PROFILE_PROC
   end
   def stop_profile
@@ -42,9 +31,8 @@ module_function
   end
   def print_profile(f)
     stop_profile
-    total = Float(Times::times[0]) - @@start
+    total = Float(Process.times[0]) - @@start
     if total == 0 then total = 0.01 end
-    @@map["#toplevel"][1] = total
     data = @@map.values
     data.sort!{|a,b| b[2] <=> a[2]}
     sum = 0
@@ -53,7 +41,19 @@ module_function
     for d in data
       sum += d[2]
       f.printf "%6.2f %8.2f  %8.2f %8d ", d[2]/total*100, sum, d[2], d[0]
-      f.printf "%8.2f %8.2f  %s\n", d[2]*1000/d[0], d[1]*1000/d[0], d[3]
+      f.printf "%8.2f %8.2f  %s\n", d[2]*1000/d[0], d[1]*1000/d[0], get_name(*d[3])
+    end
+    f.printf "%6.2f %8.2f  %8.2f %8d ", 0.0, total, 0.0, 1
+    f.printf "%8.2f %8.2f  %s\n", 0.0, total*1000, "#toplevel"
+  end
+  def get_name(klass, id)
+    name = klass.to_s || ""
+    if klass.kind_of? Class
+      name += "#"
+    else
+      name += "."
     end
+    name + id.id2name
   end
+  private :get_name
 end