ruby-prof 0.16.2 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +15 -0
  3. data/README.rdoc +36 -5
  4. data/bin/ruby-prof +7 -2
  5. data/doc/LICENSE.html +2 -1
  6. data/doc/README_rdoc.html +42 -8
  7. data/doc/Rack.html +2 -1
  8. data/doc/Rack/RubyProf.html +25 -18
  9. data/doc/Rack/RubyProf/RackProfiler.html +343 -0
  10. data/doc/RubyProf.html +14 -2
  11. data/doc/RubyProf/AbstractPrinter.html +91 -12
  12. data/doc/RubyProf/AggregateCallInfo.html +2 -1
  13. data/doc/RubyProf/CallInfo.html +18 -78
  14. data/doc/RubyProf/CallInfoPrinter.html +2 -1
  15. data/doc/RubyProf/CallInfoVisitor.html +2 -1
  16. data/doc/RubyProf/CallStackPrinter.html +35 -29
  17. data/doc/RubyProf/CallTreePrinter.html +98 -14
  18. data/doc/RubyProf/Cmd.html +11 -5
  19. data/doc/RubyProf/DeprecationWarnings.html +148 -0
  20. data/doc/RubyProf/DotPrinter.html +2 -1
  21. data/doc/RubyProf/FlatPrinter.html +2 -1
  22. data/doc/RubyProf/FlatPrinterWithLineNumbers.html +7 -5
  23. data/doc/RubyProf/GraphHtmlPrinter.html +18 -12
  24. data/doc/RubyProf/GraphPrinter.html +2 -1
  25. data/doc/RubyProf/MethodInfo.html +19 -88
  26. data/doc/RubyProf/MultiPrinter.html +231 -17
  27. data/doc/RubyProf/Profile.html +184 -39
  28. data/doc/RubyProf/Profile/ExcludeCommonMethods.html +411 -0
  29. data/doc/RubyProf/Profile/LegacyMethodElimination.html +158 -0
  30. data/doc/RubyProf/ProfileTask.html +2 -1
  31. data/doc/RubyProf/Thread.html +4 -39
  32. data/doc/created.rid +21 -19
  33. data/doc/css/fonts.css +6 -6
  34. data/doc/examples/flat_txt.html +2 -1
  35. data/doc/examples/graph_html.html +2 -1
  36. data/doc/examples/graph_txt.html +2 -1
  37. data/doc/index.html +47 -7
  38. data/doc/js/darkfish.js +7 -7
  39. data/doc/js/search_index.js +1 -1
  40. data/doc/js/search_index.js.gz +0 -0
  41. data/doc/js/searcher.js +1 -0
  42. data/doc/js/searcher.js.gz +0 -0
  43. data/doc/table_of_contents.html +190 -80
  44. data/ext/ruby_prof/extconf.rb +4 -0
  45. data/ext/ruby_prof/rp_call_info.c +19 -1
  46. data/ext/ruby_prof/rp_call_info.h +8 -3
  47. data/ext/ruby_prof/rp_method.c +282 -57
  48. data/ext/ruby_prof/rp_method.h +28 -5
  49. data/ext/ruby_prof/rp_stack.c +69 -24
  50. data/ext/ruby_prof/rp_stack.h +21 -9
  51. data/ext/ruby_prof/rp_thread.c +4 -1
  52. data/ext/ruby_prof/ruby_prof.c +142 -39
  53. data/ext/ruby_prof/ruby_prof.h +3 -0
  54. data/lib/ruby-prof.rb +10 -0
  55. data/lib/ruby-prof/call_info.rb +0 -11
  56. data/lib/ruby-prof/method_info.rb +4 -12
  57. data/lib/ruby-prof/printers/abstract_printer.rb +19 -1
  58. data/lib/ruby-prof/printers/call_info_printer.rb +1 -1
  59. data/lib/ruby-prof/printers/call_stack_printer.rb +9 -4
  60. data/lib/ruby-prof/printers/call_tree_printer.rb +15 -2
  61. data/lib/ruby-prof/printers/flat_printer_with_line_numbers.rb +23 -4
  62. data/lib/ruby-prof/printers/graph_html_printer.rb +10 -5
  63. data/lib/ruby-prof/printers/graph_printer.rb +2 -2
  64. data/lib/ruby-prof/printers/multi_printer.rb +44 -18
  65. data/lib/ruby-prof/profile.rb +13 -42
  66. data/lib/ruby-prof/profile/exclude_common_methods.rb +201 -0
  67. data/lib/ruby-prof/profile/legacy_method_elimination.rb +49 -0
  68. data/lib/ruby-prof/rack.rb +130 -51
  69. data/lib/ruby-prof/thread.rb +0 -6
  70. data/lib/ruby-prof/version.rb +1 -1
  71. data/ruby-prof.gemspec +4 -3
  72. data/test/aggregate_test.rb +1 -1
  73. data/test/exclude_methods_test.rb +146 -0
  74. data/test/line_number_test.rb +12 -3
  75. data/test/multi_printer_test.rb +23 -2
  76. data/test/no_method_class_test.rb +1 -1
  77. data/test/printers_test.rb +21 -1
  78. data/test/rack_test.rb +64 -0
  79. data/test/recursive_test.rb +15 -15
  80. data/test/test_helper.rb +11 -0
  81. metadata +20 -13
@@ -42,11 +42,14 @@ typedef struct
42
42
  {
43
43
  VALUE running;
44
44
  VALUE paused;
45
+
45
46
  prof_measurer_t* measurer;
46
47
  VALUE threads;
48
+
47
49
  st_table* threads_tbl;
48
50
  st_table* exclude_threads_tbl;
49
51
  st_table* include_threads_tbl;
52
+ st_table* exclude_methods_tbl;
50
53
  thread_data_t* last_thread_data;
51
54
  double measurement_at_pause_resume;
52
55
  int merge_fibers;
@@ -8,6 +8,16 @@ rescue LoadError
8
8
  require "ruby_prof.so"
9
9
  end
10
10
 
11
+ module RubyProf
12
+ module DeprecationWarnings
13
+ def deprecation_warning(feature, recommendation = nil)
14
+ $stderr.puts "DEPRECATION WARNING: #{feature}"
15
+ $stderr.puts recommendation unless recommendation.nil?
16
+ end
17
+ end
18
+ extend DeprecationWarnings
19
+ end
20
+
11
21
  require 'ruby-prof/version'
12
22
  require 'ruby-prof/call_info'
13
23
  require 'ruby-prof/compatibility'
@@ -9,17 +9,6 @@ module RubyProf
9
9
  # children: array of call info children (can be empty)
10
10
  # target: method info (containing an array of call infos)
11
11
 
12
- attr_reader :recursive
13
-
14
- def detect_recursion(visited_methods = Hash.new(0))
15
- @recursive = (visited_methods[target] += 1) > 1
16
- children.each do |child|
17
- child.detect_recursion(visited_methods)
18
- end
19
- visited_methods.delete(target) if (visited_methods[target] -= 1) == 0
20
- return @recursive
21
- end
22
-
23
12
  def children_time
24
13
  children.inject(0) do |sum, call_info|
25
14
  sum += call_info.total_time
@@ -18,10 +18,6 @@ module RubyProf
18
18
  end
19
19
  end
20
20
 
21
- def detect_recursion
22
- call_infos.each(&:detect_recursion)
23
- end
24
-
25
21
  def called
26
22
  @called ||= begin
27
23
  call_infos.inject(0) do |sum, call_info|
@@ -33,7 +29,7 @@ module RubyProf
33
29
  def total_time
34
30
  @total_time ||= begin
35
31
  call_infos.inject(0) do |sum, call_info|
36
- sum += call_info.total_time unless call_info.recursive
32
+ sum += call_info.total_time if !call_info.recursive?
37
33
  sum
38
34
  end
39
35
  end
@@ -42,7 +38,7 @@ module RubyProf
42
38
  def self_time
43
39
  @self_time ||= begin
44
40
  call_infos.inject(0) do |sum, call_info|
45
- sum += call_info.self_time unless call_info.recursive
41
+ sum += call_info.self_time if !call_info.recursive?
46
42
  sum
47
43
  end
48
44
  end
@@ -51,7 +47,7 @@ module RubyProf
51
47
  def wait_time
52
48
  @wait_time ||= begin
53
49
  call_infos.inject(0) do |sum, call_info|
54
- sum += call_info.wait_time unless call_info.recursive
50
+ sum += call_info.wait_time if !call_info.recursive?
55
51
  sum
56
52
  end
57
53
  end
@@ -60,7 +56,7 @@ module RubyProf
60
56
  def children_time
61
57
  @children_time ||= begin
62
58
  call_infos.inject(0) do |sum, call_info|
63
- sum += call_info.children_time unless call_info.recursive
59
+ sum += call_info.children_time if !call_info.recursive?
64
60
  sum
65
61
  end
66
62
  end
@@ -78,10 +74,6 @@ module RubyProf
78
74
  end
79
75
  end
80
76
 
81
- def recursive?
82
- (@recursive ||= call_infos.detect(&:recursive) ? :true : :false) == :true
83
- end
84
-
85
77
  def children
86
78
  @children ||= call_infos.map(&:children).flatten
87
79
  end
@@ -26,6 +26,9 @@ module RubyProf
26
26
  # Available values are :total_time, :self_time,
27
27
  # :wait_time, :children_time
28
28
  # Default value is :total_time
29
+ # :editor_uri - Specifies editor uri scheme used for opening files
30
+ # e.g. :atm or :mvim. For OS X default is :txmt.
31
+ # Use RUBY_PROF_EDITOR_URI environment variable to overide.
29
32
  def setup_options(options = {})
30
33
  @options = options
31
34
  end
@@ -42,6 +45,16 @@ module RubyProf
42
45
  @options[:sort_method] || :total_time
43
46
  end
44
47
 
48
+ def editor_uri
49
+ default_uri = if RUBY_PLATFORM =~ /darwin/ \
50
+ && !ENV['RUBY_PROF_EDITOR_URI']
51
+ 'txmt'
52
+ else
53
+ false
54
+ end
55
+ ENV['RUBY_PROF_EDITOR_URI'] || @options[:editor_uri] || default_uri
56
+ end
57
+
45
58
  def method_name(method)
46
59
  name = method.full_name
47
60
  if print_file
@@ -81,5 +94,10 @@ module RubyProf
81
94
 
82
95
  def print_footer(thread)
83
96
  end
97
+
98
+ # whether this printer need a :path option pointing to a directory
99
+ def self.needs_dir?
100
+ false
101
+ end
84
102
  end
85
- end
103
+ end
@@ -31,7 +31,7 @@ module RubyProf
31
31
  @output << "wt:#{sprintf("%#{TIME_WIDTH}.2f", call_info.wait_time)}, "
32
32
  @output << "ct:#{sprintf("%#{TIME_WIDTH}.2f", call_info.children_time)}, "
33
33
  @output << "call:#{call_info.called}, "
34
- @output << "rec:#{call_info.recursive}"
34
+ @output << "rec:#{call_info.recursive?}"
35
35
  @output << ")"
36
36
  @output << "\n"
37
37
  end
@@ -36,9 +36,13 @@ module RubyProf
36
36
  # :application - a String to overide the name of the application,
37
37
  # as it appears on the report.
38
38
  #
39
+ # :editor_uri - Specifies editor uri scheme used for opening files
40
+ # e.g. :atm or :mvim. For OS X default is :txmt.
41
+ # Use RUBY_PROF_EDITOR_URI environment variable to overide.
39
42
  def print(output = STDOUT, options = {})
40
43
  @output = output
41
44
  setup_options(options)
45
+ @editor = editor_uri
42
46
  if @graph_html = options.delete(:graph)
43
47
  @graph_html = "file://" + @graph_html if @graph_html[0]=="/"
44
48
  end
@@ -52,7 +56,7 @@ module RubyProf
52
56
  @result.threads.each do |thread|
53
57
  @current_thread_id = thread.fiber_id
54
58
  @overall_time = thread.total_time
55
- thread_info = "Thread: #{thread.id}"
59
+ thread_info = String.new("Thread: #{thread.id}")
56
60
  thread_info << ", Fiber: #{thread.fiber_id}" unless thread.id == thread.fiber_id
57
61
  thread_info << " (#{"%4.2f%%" % ((@overall_time/@overall_threads_time)*100)} ~ #{@overall_time})"
58
62
  @output.print "<div class=\"thread\">#{thread_info}</div>"
@@ -116,8 +120,10 @@ module RubyProf
116
120
  if file =~ /\/ruby_runtime$/
117
121
  h(name(call_info))
118
122
  else
119
- if RUBY_PLATFORM =~ /darwin/
120
- "<a href=\"txmt://open?url=file://#{file}&line=#{method.line}\">#{h(name(call_info))}</a>"
123
+ if @editor
124
+ "<a href=\"#{@editor}://" \
125
+ "open?url=file://#{file}&line=#{method.line}\">" \
126
+ "#{h(name(call_info))}</a>"
121
127
  else
122
128
  "<a href=\"file://#{file}##{method.line}\">#{h(name(call_info))}</a>"
123
129
  end
@@ -257,4 +263,3 @@ end_help
257
263
  end
258
264
  end
259
265
  end
260
-
@@ -44,11 +44,20 @@ module RubyProf
44
44
  end
45
45
 
46
46
  def print(options = {})
47
+ validate_print_params(options)
47
48
  setup_options(options)
48
49
  determine_event_specification_and_value_scale
49
50
  print_threads
50
51
  end
51
52
 
53
+ def validate_print_params(options)
54
+ if options.is_a?(IO)
55
+ raise ArgumentError, "#{self.class.name}#print cannot print to IO objects"
56
+ elsif !options.is_a?(Hash)
57
+ raise ArgumentError, "#{self.class.name}#print requires an options hash"
58
+ end
59
+ end
60
+
52
61
  def print_threads
53
62
  remove_subsidiary_files_from_previous_profile_runs
54
63
  # TODO: merge fibers of a given thread here, instead of relying
@@ -79,6 +88,10 @@ module RubyProf
79
88
  @options[:path] || "."
80
89
  end
81
90
 
91
+ def self.needs_dir?
92
+ true
93
+ end
94
+
82
95
  def base_name
83
96
  @options[:profile] || "profile"
84
97
  end
@@ -110,7 +123,7 @@ module RubyProf
110
123
  def print_method(output, method)
111
124
  # Print out the file and method name
112
125
  output << "fl=#{file(method)}\n"
113
- output << "fn=#{method_name(method)}\n"
126
+ output << "fn=#{method.calltree_name}\n"
114
127
 
115
128
  # Now print out the function line number and its self time
116
129
  output << "#{method.line} #{convert(method.self_time)}\n"
@@ -118,7 +131,7 @@ module RubyProf
118
131
  # Now print out all the children methods
119
132
  method.children.each do |callee|
120
133
  output << "cfl=#{file(callee.target)}\n"
121
- output << "cfn=#{method_name(callee.target)}\n"
134
+ output << "cfn=#{callee.target.calltree_name}\n"
122
135
  output << "calls=#{callee.called} #{callee.line}\n"
123
136
 
124
137
  # Print out total times here!
@@ -13,6 +13,7 @@ module RubyProf
13
13
  #
14
14
  class FlatPrinterWithLineNumbers < FlatPrinter
15
15
  def print_methods(thread)
16
+ @editor = editor_uri
16
17
  total_time = thread.total_time
17
18
 
18
19
  methods = thread.methods.sort_by(&sort_method).reverse
@@ -38,8 +39,8 @@ module RubyProf
38
39
  if method.source_file == 'ruby_runtime'
39
40
  @output << "\n"
40
41
  else
41
- @output << "\n defined at:\n"
42
- @output << " %s:%s\n" % [File.expand_path(method.source_file), method.line]
42
+ @output << "\n defined at:\n"
43
+ @output << defined_at_format % [File.expand_path(method.source_file), method.line]
43
44
  end
44
45
 
45
46
  callers = []
@@ -52,13 +53,31 @@ module RubyProf
52
53
  callers.uniq!
53
54
 
54
55
  unless callers.empty?
55
- @output << " called from:\n"
56
+ @output << " called from:\n"
56
57
  callers.each do |args|
57
- @output << " %s (%s:%s)\n" % args
58
+ @output << called_from_format % args
58
59
  end
59
60
  end
60
61
  @output << "\n"
61
62
  end
62
63
  end
64
+
65
+ private
66
+
67
+ def defined_at_format
68
+ if @editor
69
+ " #{@editor}://open?url=file://%s&line=%s\n"
70
+ else
71
+ " %s:%s\n"
72
+ end
73
+ end
74
+
75
+ def called_from_format
76
+ if @editor
77
+ " %s (#{@editor}://open?url=file://%s&line=%s)\n"
78
+ else
79
+ " %s (%s:%s)\n"
80
+ end
81
+ end
63
82
  end
64
83
  end
@@ -20,6 +20,9 @@ module RubyProf
20
20
  # :template - specify an ERB template to use, instead of the
21
21
  # built-in self.template
22
22
  #
23
+ # :editor_uri - Specifies editor uri scheme used for opening files
24
+ # e.g. :atm or :mvim. For OS X default is :txmt.
25
+ # Use RUBY_PROF_EDITOR_URI environment variable to overide.
23
26
 
24
27
  class GraphHtmlPrinter < AbstractPrinter
25
28
  include ERB::Util
@@ -36,6 +39,7 @@ module RubyProf
36
39
  def print(output = STDOUT, options = {})
37
40
  @output = output
38
41
  setup_options(options)
42
+ @editor = editor_uri
39
43
  @output << @erb.result(binding).split("\n").map(&:rstrip).join("\n") << "\n"
40
44
  end
41
45
 
@@ -63,8 +67,10 @@ module RubyProf
63
67
  if srcfile =~ /\/ruby_runtime$/
64
68
  ""
65
69
  else
66
- if RUBY_PLATFORM =~ /darwin/
67
- "<a href=\"txmt://open?url=file://#{h srcfile}&line=#{linenum}\" title=\"#{h srcfile}:#{linenum}\">#{linenum}</a>"
70
+ if @editor
71
+ "<a href=\"#{@editor}://" \
72
+ "open?url=file://#{h srcfile}&line=#{linenum}\"" \
73
+ "title=\"#{h srcfile}:#{linenum}\">#{linenum}</a>"
68
74
  else
69
75
  "<a href=\"file://#{h srcfile}##{linenum}\" title=\"#{h srcfile}:#{linenum}\">#{linenum}</a>"
70
76
  end
@@ -194,8 +200,8 @@ module RubyProf
194
200
  </tr>
195
201
  <% end %>
196
202
  <tr class="method">
197
- <td><%= sprintf("%.2f\%", total_percentage) %></td>
198
- <td><%= sprintf("%.2f\%", self_percentage) %></td>
203
+ <td><%= sprintf("%.2f%%", total_percentage) %></td>
204
+ <td><%= sprintf("%.2f%%", self_percentage) %></td>
199
205
  <td><%= sprintf("%.2f", method.total_time) %></td>
200
206
  <td><%= sprintf("%.2f", method.self_time) %></td>
201
207
  <td><%= sprintf("%.2f", method.wait_time) %></td>
@@ -241,4 +247,3 @@ module RubyProf
241
247
  end
242
248
  end
243
249
  end
244
-
@@ -56,8 +56,8 @@ module RubyProf
56
56
  print_parents(thread, method)
57
57
 
58
58
  # 1 is for % sign
59
- @output << sprintf("%#{PERCENTAGE_WIDTH-1}.2f\%", total_percentage)
60
- @output << sprintf("%#{PERCENTAGE_WIDTH-1}.2f\%", self_percentage)
59
+ @output << sprintf("%#{PERCENTAGE_WIDTH-1}.2f%%", total_percentage)
60
+ @output << sprintf("%#{PERCENTAGE_WIDTH-1}.2f%%", self_percentage)
61
61
  @output << sprintf("%#{TIME_WIDTH}.3f", method.total_time)
62
62
  @output << sprintf("%#{TIME_WIDTH}.3f", method.self_time)
63
63
  @output << sprintf("%#{TIME_WIDTH}.3f", method.wait_time)
@@ -5,33 +5,30 @@ module RubyProf
5
5
  # one profiling run. Currently prints a flat profile, a callgrind
6
6
  # profile, a call stack profile and a graph profile.
7
7
  class MultiPrinter
8
- def initialize(result)
9
- @stack_printer = CallStackPrinter.new(result)
10
- @graph_printer = GraphHtmlPrinter.new(result)
11
- @tree_printer = CallTreePrinter.new(result)
12
- @flat_printer = FlatPrinter.new(result)
8
+ def initialize(result, printers = [:stack, :graph, :tree, :flat])
9
+ @stack_printer = CallStackPrinter.new(result) if printers.include?(:stack)
10
+ @graph_printer = GraphHtmlPrinter.new(result) if printers.include?(:graph)
11
+ @tree_printer = CallTreePrinter.new(result) if printers.include?(:tree)
12
+ @flat_printer = FlatPrinter.new(result) if printers.include?(:flat)
13
+ end
14
+
15
+ def self.needs_dir?
16
+ true
13
17
  end
14
18
 
15
19
  # create profile files under options[:path] or the current
16
20
  # directory. options[:profile] is used as the base name for the
17
21
  # pofile file, defaults to "profile".
18
22
  def print(options)
23
+ validate_print_params(options)
24
+
19
25
  @profile = options.delete(:profile) || "profile"
20
26
  @directory = options.delete(:path) || File.expand_path(".")
21
27
 
22
- File.open(stack_profile, "w") do |f|
23
- @stack_printer.print(f, options.merge(:graph => "#{@profile}.graph.html"))
24
- end
25
-
26
- File.open(graph_profile, "w") do |f|
27
- @graph_printer.print(f, options)
28
- end
29
-
30
- @tree_printer.print(options.merge(:path => @directory, :profile => @profile))
31
-
32
- File.open(flat_profile, "w") do |f|
33
- @flat_printer.print(f, options)
34
- end
28
+ print_to_stack(options) if @stack_printer
29
+ print_to_graph(options) if @graph_printer
30
+ print_to_tree(options) if @tree_printer
31
+ print_to_flat(options) if @flat_printer
35
32
  end
36
33
 
37
34
  # the name of the call stack profile file
@@ -54,5 +51,34 @@ module RubyProf
54
51
  "#{@directory}/#{@profile}.flat.txt"
55
52
  end
56
53
 
54
+ def print_to_stack(options)
55
+ File.open(stack_profile, "w") do |f|
56
+ @stack_printer.print(f, options.merge(:graph => "#{@profile}.graph.html"))
57
+ end
58
+ end
59
+
60
+ def print_to_graph(options)
61
+ File.open(graph_profile, "w") do |f|
62
+ @graph_printer.print(f, options)
63
+ end
64
+ end
65
+
66
+ def print_to_tree(options)
67
+ @tree_printer.print(options.merge(:path => @directory, :profile => @profile))
68
+ end
69
+
70
+ def print_to_flat(options)
71
+ File.open(flat_profile, "w") do |f|
72
+ @flat_printer.print(f, options)
73
+ end
74
+ end
75
+
76
+ def validate_print_params(options)
77
+ if options.is_a?(IO)
78
+ raise ArgumentError, "#{self.class.name}#print cannot print to IO objects"
79
+ elsif !options.is_a?(Hash)
80
+ raise ArgumentError, "#{self.class.name}#print requires an options hash"
81
+ end
82
+ end
57
83
  end
58
84
  end
@@ -1,55 +1,26 @@
1
1
  # encoding: utf-8
2
2
 
3
+ require 'ruby-prof/profile/exclude_common_methods'
4
+ require 'ruby-prof/profile/legacy_method_elimination'
5
+
3
6
  module RubyProf
4
7
  class Profile
5
- # This method gets called once profiling has been completed
6
- # but before results are returned to the user. Thus it provides
7
- # a hook to do any necessary post-processing on the call graph.
8
- def post_process
9
- self.threads.each do |thread|
10
- thread.detect_recursion
11
- end
12
- end
8
+ include LegacyMethodElimination
13
9
 
14
- # eliminate some calls from the graph by merging the information into callers.
15
- # matchers can be a list of strings or regular expressions or the name of a file containing regexps.
16
- def eliminate_methods!(matchers)
17
- matchers = read_regexps_from_file(matchers) if matchers.is_a?(String)
18
- eliminated = []
19
- threads.each do |thread|
20
- matchers.each{ |matcher| eliminated.concat(eliminate_methods(thread.methods, matcher)) }
21
- end
22
- eliminated
10
+ # Hides methods that, when represented as a call graph, have
11
+ # extremely large in and out degrees and make navigation impossible.
12
+ def exclude_common_methods!
13
+ ExcludeCommonMethods.apply!(self)
23
14
  end
24
15
 
25
- private
26
-
27
- # read regexps from file
28
- def read_regexps_from_file(file_name)
29
- matchers = []
30
- File.open(file_name).each_line do |l|
31
- next if (l =~ /^(#.*|\s*)$/) # emtpy lines and lines starting with #
32
- matchers << Regexp.new(l.strip)
16
+ def exclude_methods!(mod, *method_or_methods)
17
+ [method_or_methods].flatten.each do |name|
18
+ exclude_method!(mod, name)
33
19
  end
34
20
  end
35
21
 
36
- # eliminate methods matching matcher
37
- def eliminate_methods(methods, matcher)
38
- eliminated = []
39
- i = 0
40
- while i < methods.size
41
- method_info = methods[i]
42
- method_name = method_info.full_name
43
- if matcher === method_name
44
- raise "can't eliminate root method" if method_info.root?
45
- eliminated << methods.delete_at(i)
46
- method_info.eliminate!
47
- else
48
- i += 1
49
- end
50
- end
51
- eliminated
22
+ def exclude_singleton_methods!(mod, *method_or_methods)
23
+ exclude_methods!(mod.singleton_class, *method_or_methods)
52
24
  end
53
-
54
25
  end
55
26
  end