ruby-prof 0.11.2-x86-mingw32 → 0.12.1-x86-mingw32

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 (66) hide show
  1. data/CHANGES +27 -0
  2. data/README.rdoc +15 -15
  3. data/Rakefile +5 -0
  4. data/bin/ruby-prof +274 -265
  5. data/ext/ruby_prof/rp_call_info.c +33 -24
  6. data/ext/ruby_prof/rp_call_info.h +2 -1
  7. data/ext/ruby_prof/rp_measure.c +1 -1
  8. data/ext/ruby_prof/rp_measure.h +1 -1
  9. data/ext/ruby_prof/rp_measure_allocations.c +1 -1
  10. data/ext/ruby_prof/rp_measure_cpu_time.c +1 -1
  11. data/ext/ruby_prof/rp_measure_gc_runs.c +1 -1
  12. data/ext/ruby_prof/rp_measure_gc_time.c +1 -1
  13. data/ext/ruby_prof/rp_measure_memory.c +1 -1
  14. data/ext/ruby_prof/rp_measure_process_time.c +2 -2
  15. data/ext/ruby_prof/rp_measure_wall_time.c +2 -2
  16. data/ext/ruby_prof/rp_method.c +11 -24
  17. data/ext/ruby_prof/rp_method.h +2 -3
  18. data/ext/ruby_prof/rp_stack.c +55 -14
  19. data/ext/ruby_prof/rp_stack.h +10 -10
  20. data/ext/ruby_prof/rp_thread.c +30 -21
  21. data/ext/ruby_prof/rp_thread.h +3 -3
  22. data/ext/ruby_prof/ruby_prof.c +9 -88
  23. data/ext/ruby_prof/ruby_prof.h +1 -1
  24. data/ext/ruby_prof/vc/ruby_prof.sln +12 -6
  25. data/ext/ruby_prof/vc/ruby_prof_18.vcxproj +2 -0
  26. data/ext/ruby_prof/vc/{ruby_prof.vcxproj → ruby_prof_19.vcxproj} +4 -1
  27. data/ext/ruby_prof/vc/ruby_prof_20.vcxproj +112 -0
  28. data/ext/ruby_prof/version.h +4 -4
  29. data/lib/1.8/ruby_prof.so +0 -0
  30. data/lib/1.9/ruby_prof.so +0 -0
  31. data/lib/2.0/ruby_prof.so +0 -0
  32. data/lib/ruby-prof.rb +1 -0
  33. data/lib/ruby-prof/call_info.rb +1 -1
  34. data/lib/ruby-prof/call_info_visitor.rb +4 -2
  35. data/lib/ruby-prof/compatibility.rb +13 -3
  36. data/lib/ruby-prof/method_info.rb +1 -1
  37. data/lib/ruby-prof/printers/call_info_printer.rb +1 -1
  38. data/lib/ruby-prof/printers/call_stack_printer.rb +3 -3
  39. data/lib/ruby-prof/printers/dot_printer.rb +2 -2
  40. data/lib/ruby-prof/printers/flat_printer.rb +4 -4
  41. data/lib/ruby-prof/printers/flat_printer_with_line_numbers.rb +2 -2
  42. data/lib/ruby-prof/printers/graph_html_printer.rb +3 -4
  43. data/lib/ruby-prof/printers/graph_printer.rb +15 -15
  44. data/lib/ruby-prof/profile.rb +1 -1
  45. data/lib/ruby-prof/rack.rb +0 -5
  46. data/lib/ruby-prof/thread.rb +22 -0
  47. data/ruby-prof.gemspec +2 -1
  48. data/test/basic_test.rb +77 -45
  49. data/test/call_info_test.rb +78 -0
  50. data/test/call_info_visitor_test.rb +1 -1
  51. data/test/dynamic_method_test.rb +14 -8
  52. data/test/measure_cpu_time_test.rb +23 -12
  53. data/test/measure_process_time_test.rb +21 -170
  54. data/test/measure_wall_time_test.rb +59 -13
  55. data/test/method_elimination_test.rb +30 -19
  56. data/test/pause_resume_test.rb +129 -22
  57. data/test/prime.rb +1 -2
  58. data/test/printers_test.rb +8 -17
  59. data/test/recursive_test.rb +6 -50
  60. data/test/test_helper.rb +30 -10
  61. data/test/test_suite.rb +1 -2
  62. metadata +23 -7
  63. data/test/bug_test.rb +0 -6
  64. data/test/gc_test.rb +0 -35
  65. data/test/pause_test.rb +0 -57
  66. data/test/prime_test.rb +0 -13
@@ -11,19 +11,17 @@ require 'tmpdir'
11
11
  # \
12
12
  # B
13
13
 
14
- class ESTPT
15
- def a
16
- 100.times{b}
17
- 300.times{c}
18
- c;c;c
14
+ module MethodElimination
15
+ def self.a
16
+ 1.times {|i| c}
19
17
  end
20
18
 
21
- def b
22
- sleep 0
19
+ def self.b
20
+ sleep 0.1
23
21
  end
24
22
 
25
- def c
26
- 5.times{b}
23
+ def self.c
24
+ 1.times {|i| b}
27
25
  end
28
26
  end
29
27
 
@@ -40,24 +38,37 @@ class MethodEliminationTest < Test::Unit::TestCase
40
38
  method_infos = result.threads.first.methods
41
39
  assert(m1 = method_infos[0])
42
40
  assert(c1 = m1.call_infos.first)
43
- assert_equal(c1, c1.parent = c1)
44
- assert_equal c1, c1.parent
41
+ assert_nil(c1.parent)
45
42
  end
46
43
 
47
44
  def test_methods_can_be_eliminated
48
45
  RubyProf.start
49
- 5.times{ESTPT.new.a}
46
+ 5.times {MethodElimination.a}
50
47
  result = RubyProf.stop
51
- # result.dump
52
- eliminated = result.eliminate_methods!([/Integer#times/])
53
- # puts eliminated.inspect
54
- # result.dump
55
- eliminated.each do |m|
56
- assert_method_has_been_eliminated(result, m)
57
- end
48
+
49
+ methods = result.threads.first.methods.sort.reverse
50
+
51
+ assert_equal(6, methods.count)
52
+ assert_equal('MethodEliminationTest#test_methods_can_be_eliminated', methods[0].full_name)
53
+ assert_equal('Integer#times', methods[1].full_name)
54
+ assert_equal('<Module::MethodElimination>#a', methods[2].full_name)
55
+ assert_equal('<Module::MethodElimination>#c', methods[3].full_name)
56
+ assert_equal('<Module::MethodElimination>#b', methods[4].full_name)
57
+ assert_equal('Kernel#sleep', methods[5].full_name)
58
+
59
+ result.eliminate_methods!([/Integer#times/])
60
+
61
+ methods = result.threads.first.methods.sort.reverse
62
+ assert_equal(5, methods.count)
63
+ assert_equal('MethodEliminationTest#test_methods_can_be_eliminated', methods[0].full_name)
64
+ assert_equal('<Module::MethodElimination>#a', methods[1].full_name)
65
+ assert_equal('<Module::MethodElimination>#c', methods[2].full_name)
66
+ assert_equal('<Module::MethodElimination>#b', methods[3].full_name)
67
+ assert_equal('Kernel#sleep', methods[4].full_name)
58
68
  end
59
69
 
60
70
  private
71
+
61
72
  def assert_method_has_been_eliminated(result, eliminated_method)
62
73
  result.threads.each do |thread|
63
74
  thread.methods.each do |method|
@@ -4,22 +4,72 @@
4
4
  require File.expand_path('../test_helper', __FILE__)
5
5
 
6
6
  class PauseResumeTest < Test::Unit::TestCase
7
+ def setup
8
+ # Need to use wall time for this test due to the sleep calls
9
+ RubyProf::measure_mode = RubyProf::WALL_TIME
10
+ end
11
+
12
+ def test_pause_resume
13
+ # Measured
14
+ RubyProf.start
15
+ RubyProf::C1.hello
16
+
17
+ # Not measured
18
+ RubyProf.pause
19
+ sleep 1
20
+ RubyProf::C1.hello
21
+
22
+ # Measured
23
+ RubyProf.resume
24
+ RubyProf::C1.hello
25
+
26
+ result = RubyProf.stop
27
+
28
+ # Length should be 3:
29
+ # PauseResumeTest#test_pause_resume
30
+ # <Class::RubyProf::C1>#hello
31
+ # Kernel#sleep
32
+
33
+ methods = result.threads.first.methods.sort_by {|method_info| method_info.full_name}
34
+ assert_equal(3, methods.length)
35
+
36
+ # Check the names
37
+ assert_equal('<Class::RubyProf::C1>#hello', methods[0].full_name)
38
+ assert_equal('Kernel#sleep', methods[1].full_name)
39
+ assert_equal('PauseResumeTest#test_pause_resume', methods[2].full_name)
40
+
41
+ # Check times
42
+ assert_in_delta(0.2, methods[0].total_time, 0.01)
43
+ assert_in_delta(0, methods[0].wait_time, 0.01)
44
+ assert_in_delta(0, methods[0].self_time, 0.01)
45
+
46
+ assert_in_delta(0.2, methods[1].total_time, 0.01)
47
+ assert_in_delta(0, methods[1].wait_time, 0.01)
48
+ assert_in_delta(0.2, methods[1].self_time, 0.01)
49
+
50
+ assert_in_delta(0.2, methods[2].total_time, 0.01)
51
+ assert_in_delta(0, methods[2].wait_time, 0.01)
52
+ assert_in_delta(0, methods[2].self_time, 0.01)
53
+ end
7
54
 
8
55
  # pause/resume in the same frame
9
56
  def test_pause_resume_1
10
- p= RubyProf::Profile.new(RubyProf::WALL_TIME,[])
57
+ profile = RubyProf::Profile.new(RubyProf::WALL_TIME,[])
11
58
 
12
- p.start
59
+ # Measured
60
+ profile.start
13
61
  method_1a
14
62
 
15
- p.pause
63
+ # Not measured
64
+ profile.pause
16
65
  method_1b
17
66
 
18
- p.resume
67
+ # Measured
68
+ profile.resume
19
69
  method_1c
20
70
 
21
- r= p.stop
22
- assert_in_delta(0.6, r.threads[0].methods.select{|m| m.full_name =~ /test_pause_resume_1$/}[0].total_time, 0.05)
71
+ result = profile.stop
72
+ assert_in_delta(0.6, result.threads[0].methods.select{|m| m.full_name =~ /test_pause_resume_1$/}[0].total_time, 0.05)
23
73
  end
24
74
  def method_1a; sleep 0.2 end
25
75
  def method_1b; sleep 1 end
@@ -27,35 +77,92 @@ class PauseResumeTest < Test::Unit::TestCase
27
77
 
28
78
  # pause in parent frame, resume in child
29
79
  def test_pause_resume_2
30
- p= RubyProf::Profile.new(RubyProf::WALL_TIME,[])
80
+ profile = RubyProf::Profile.new(RubyProf::WALL_TIME,[])
31
81
 
32
- p.start
82
+ # Measured
83
+ profile.start
33
84
  method_2a
34
85
 
35
- p.pause
86
+ # Not Measured
87
+ profile.pause
36
88
  sleep 0.5
37
- method_2b(p)
89
+ method_2b(profile)
38
90
 
39
- r= p.stop
40
- assert_in_delta(0.6, r.threads[0].methods.select{|m| m.full_name =~ /test_pause_resume_2$/}[0].total_time, 0.05)
91
+ result = profile.stop
92
+ assert_in_delta(0.6, result.threads[0].methods.select{|m| m.full_name =~ /test_pause_resume_2$/}[0].total_time, 0.05)
41
93
  end
42
94
  def method_2a; sleep 0.2 end
43
- def method_2b(p); sleep 0.5; p.resume; sleep 0.4 end
95
+ def method_2b(profile); sleep 0.5; profile.resume; sleep 0.4 end
44
96
 
45
97
  # pause in child frame, resume in parent
46
98
  def test_pause_resume_3
47
- p= RubyProf::Profile.new(RubyProf::WALL_TIME,[])
48
-
49
- p.start
50
- method_3a(p)
99
+ profile = RubyProf::Profile.new(RubyProf::WALL_TIME,[])
51
100
 
101
+ # Measured
102
+ profile.start
103
+ method_3a(profile)
52
104
  sleep 0.5
53
- p.resume
105
+
106
+ profile.resume
54
107
  method_3b
55
108
 
56
- r= p.stop
57
- assert_in_delta(0.6, r.threads[0].methods.select{|m| m.full_name =~ /test_pause_resume_3$/}[0].total_time, 0.05)
109
+ result = profile.stop
110
+ assert_in_delta(0.6, result.threads[0].methods.select{|m| m.full_name =~ /test_pause_resume_3$/}[0].total_time, 0.05)
58
111
  end
59
- def method_3a(p); sleep 0.2; p.pause; sleep 0.5 end
112
+ def method_3a(profile); sleep 0.2; profile.pause; sleep 0.5 end
60
113
  def method_3b; sleep 0.4 end
61
- end
114
+
115
+ def test_pause_seq
116
+ profile = RubyProf::Profile.new(RubyProf::WALL_TIME,[])
117
+ profile.start ; assert !profile.paused?
118
+ profile.pause ; assert profile.paused?
119
+ profile.resume; assert !profile.paused?
120
+ profile.pause ; assert profile.paused?
121
+ profile.pause ; assert profile.paused?
122
+ profile.resume; assert !profile.paused?
123
+ profile.resume; assert !profile.paused?
124
+ profile.stop ; assert !profile.paused?
125
+ end
126
+
127
+ def test_pause_block
128
+ profile = RubyProf::Profile.new(RubyProf::WALL_TIME,[])
129
+ profile.start
130
+ profile.pause
131
+ assert profile.paused?
132
+
133
+ times_block_invoked = 0
134
+ retval= profile.resume{
135
+ times_block_invoked += 1
136
+ 120 + times_block_invoked
137
+ }
138
+ assert_equal 1, times_block_invoked
139
+ assert profile.paused?
140
+
141
+ assert_equal 121, retval, "resume() should return the result of the given block."
142
+
143
+ profile.stop
144
+ end
145
+
146
+ def test_pause_block_with_error
147
+ profile = RubyProf::Profile.new(RubyProf::WALL_TIME,[])
148
+ profile.start
149
+ profile.pause
150
+ assert profile.paused?
151
+
152
+ begin
153
+ profile.resume{ raise }
154
+ flunk 'Exception expected.'
155
+ rescue
156
+ assert profile.paused?
157
+ end
158
+
159
+ profile.stop
160
+ end
161
+
162
+ def test_resume_when_not_paused
163
+ profile = RubyProf::Profile.new(RubyProf::WALL_TIME,[])
164
+ profile.start ; assert !profile.paused?
165
+ profile.resume; assert !profile.paused?
166
+ profile.stop ; assert !profile.paused?
167
+ end
168
+ end
data/test/prime.rb CHANGED
@@ -34,7 +34,6 @@ def find_largest(primes)
34
34
  # Intentionally use upto for example purposes
35
35
  # (upto is also called from is_prime)
36
36
  0.upto(primes.length-1) do |i|
37
- sleep(0.02)
38
37
  prime = primes[i]
39
38
  if prime > largest
40
39
  largest = prime
@@ -51,5 +50,5 @@ def run_primes(length=10, maxnum=1000)
51
50
  primes = find_primes(random_array)
52
51
 
53
52
  # Find the largest primes
54
- largest = find_largest(primes)
53
+ find_largest(primes)
55
54
  end
@@ -7,20 +7,11 @@ require 'fileutils'
7
7
 
8
8
  # -- Tests ----
9
9
  class PrintersTest < Test::Unit::TestCase
10
- def go
11
- run_primes(1000)
12
- end
13
-
14
10
  def setup
15
11
  # WALL_TIME so we can use sleep in our test and get same measurements on linux and windows
16
12
  RubyProf::measure_mode = RubyProf::WALL_TIME
17
13
  @result = RubyProf.profile do
18
- begin
19
- run_primes(1000)
20
- go
21
- rescue => e
22
- p e
23
- end
14
+ run_primes(200)
24
15
  end
25
16
  end
26
17
 
@@ -45,7 +36,6 @@ class PrintersTest < Test::Unit::TestCase
45
36
 
46
37
  printer = RubyProf::GraphPrinter.new(@result)
47
38
  printer.print(output)
48
-
49
39
  end
50
40
  end
51
41
 
@@ -111,9 +101,9 @@ class PrintersTest < Test::Unit::TestCase
111
101
  printer = RubyProf::GraphHtmlPrinter.new(@result)
112
102
  printer.print(output)
113
103
 
114
- assert_match( /DTD HTML 4\.01/i, output )
115
- assert_match( %r{<th>Total Time</th>}i, output )
116
- assert_match( /Object#run_primes/i, output )
104
+ assert_match(/DTD HTML 4\.01/i, output)
105
+ assert_match( %r{<th>Total Time</th>}i, output)
106
+ assert_match(/Object#run_primes/i, output)
117
107
  end
118
108
 
119
109
  def test_graph_string
@@ -121,9 +111,9 @@ class PrintersTest < Test::Unit::TestCase
121
111
  printer = RubyProf::GraphPrinter.new(@result)
122
112
  printer.print(output)
123
113
 
124
- assert_match( /Thread ID: -?\d+/i, output )
125
- assert_match( /Total Time: \d+\.\d+/i, output )
126
- assert_match( /Object#run_primes/i, output )
114
+ assert_match(/Thread ID: -?\d+/i, output)
115
+ assert_match(/Total Time: \d+\.\d+/i, output)
116
+ assert_match(/Object#run_primes/i, output)
127
117
  end
128
118
 
129
119
  def test_call_tree_string
@@ -259,6 +249,7 @@ class PrintersTest < Test::Unit::TestCase
259
249
  end
260
250
 
261
251
  def assert_sorted array
252
+ array = array.map{|n| n.to_f} # allow for > 10s times to sort right, since lexographically 4.0 > 10.0
262
253
  assert_equal array, array.sort.reverse, "Array #{array.inspect} is not sorted"
263
254
  end
264
255
  end
@@ -43,17 +43,13 @@ class RecursiveTest < Test::Unit::TestCase
43
43
  simple(2)
44
44
  end
45
45
 
46
- methods = result.threads.first.methods.dup
47
-
48
46
  # Remove Fixnum+, Fixnum== for less than Ruby 1.9
49
- methods.delete_if do |method|
50
- method.full_name.match(/Fixnum/)
51
- end
47
+ result.eliminate_methods!(%w(Fixnum#== Fixnum#-))
52
48
 
49
+ methods = result.threads.first.methods.sort.reverse
53
50
  assert_equal(3, methods.length)
54
51
 
55
52
  # Method 0: RecursiveTest#test_simple
56
- methods.sort!.reverse!
57
53
  method = methods[0]
58
54
  assert_equal('RecursiveTest#test_simple', method.full_name)
59
55
  assert_equal(1, method.called)
@@ -80,12 +76,12 @@ class RecursiveTest < Test::Unit::TestCase
80
76
  assert_equal(2, method.call_infos.length)
81
77
 
82
78
  call_info = method.call_infos.first
83
- assert_equal(2 + (RUBY_VERSION < '1.9.0' ? 2 : 0), call_info.children.length)
79
+ assert_equal(2, call_info.children.length)
84
80
  assert_equal('RecursiveTest#test_simple->Object#simple', call_info.call_sequence)
85
81
  assert(!call_info.recursive)
86
82
 
87
83
  call_info = method.call_infos.last
88
- assert_equal(1 + (RUBY_VERSION < '1.9.0' ? 2 : 0), call_info.children.length)
84
+ assert_equal(1, call_info.children.length)
89
85
  assert_equal('RecursiveTest#test_simple->Object#simple->Object#simple', call_info.call_sequence)
90
86
  assert(call_info.recursive)
91
87
 
@@ -107,43 +103,6 @@ class RecursiveTest < Test::Unit::TestCase
107
103
  assert_equal('RecursiveTest#test_simple->Object#simple->Object#simple->Kernel#sleep', call_info.call_sequence)
108
104
  assert_equal(0, call_info.children.length)
109
105
  assert(!call_info.recursive)
110
-
111
- if RUBY_VERSION < '1.9'
112
- methods = result.threads.first.methods.dup.sort!.reverse!
113
- method = methods[3]
114
- assert_equal('Fixnum#-', method.full_name)
115
- assert_equal(2, method.called)
116
- assert_in_delta(0, method.total_time, 0.01)
117
- assert_in_delta(0, method.self_time, 0.01)
118
- assert_in_delta(0, method.wait_time, 0.01)
119
- assert_in_delta(0, method.children_time, 0.01)
120
-
121
- assert_equal(2, method.call_infos.length)
122
- call_info = method.call_infos[0]
123
- assert_equal('RecursiveTest#test_simple->Object#simple->Fixnum#-', call_info.call_sequence)
124
- assert_equal(0, call_info.children.length)
125
-
126
- call_info = method.call_infos[1]
127
- assert_equal('RecursiveTest#test_simple->Object#simple->Object#simple->Fixnum#-', call_info.call_sequence)
128
- assert_equal(0, call_info.children.length)
129
-
130
- method = methods[4]
131
- assert_equal('Fixnum#==', method.full_name)
132
- assert_equal(2, method.called)
133
- assert_in_delta(0, method.total_time, 0.01)
134
- assert_in_delta(0, method.self_time, 0.01)
135
- assert_in_delta(0, method.wait_time, 0.01)
136
- assert_in_delta(0, method.children_time, 0.01)
137
-
138
- assert_equal(2, method.call_infos.length)
139
- call_info = method.call_infos[0]
140
- assert_equal('RecursiveTest#test_simple->Object#simple->Fixnum#==', call_info.call_sequence)
141
- assert_equal(0, call_info.children.length)
142
-
143
- call_info = method.call_infos[1]
144
- assert_equal('RecursiveTest#test_simple->Object#simple->Object#simple->Fixnum#==', call_info.call_sequence)
145
- assert_equal(0, call_info.children.length)
146
- end
147
106
  end
148
107
 
149
108
  def test_cycle
@@ -151,9 +110,6 @@ class RecursiveTest < Test::Unit::TestCase
151
110
  render
152
111
  end
153
112
 
154
- printer = RubyProf::GraphPrinter.new(result)
155
- printer.print(STDOUT)
156
-
157
113
  methods = result.threads.first.methods.sort.reverse
158
114
  if RUBY_VERSION < '1.9' # Fixnum#+, Fixnum#===, Kernel#===
159
115
  assert_equal(8, methods.length)
@@ -214,7 +170,7 @@ class RecursiveTest < Test::Unit::TestCase
214
170
  assert_in_delta(5, method.total_time, 0.1)
215
171
  assert_in_delta(0, method.self_time, 0.1)
216
172
  assert_in_delta(0, method.wait_time, 0.01)
217
- assert_in_delta(5, method.children_time, 0.01)
173
+ assert_in_delta(5, method.children_time, 0.05)
218
174
 
219
175
  assert_equal(3, method.call_infos.length)
220
176
  call_info = method.call_infos[0]
@@ -256,4 +212,4 @@ class RecursiveTest < Test::Unit::TestCase
256
212
  assert_equal(0, call_info.children.length)
257
213
  assert(!call_info.recursive)
258
214
  end
259
- end
215
+ end
data/test/test_helper.rb CHANGED
@@ -1,16 +1,21 @@
1
1
  # encoding: UTF-8
2
2
 
3
+ # Make ruby 1.8.7 happy
4
+ require "rubygems"
5
+
3
6
  # Make RubyMine happy
7
+ gem "minitest"
8
+
4
9
  if ENV["RM_INFO"] || ENV["TEAMCITY_VERSION"]
5
- gem 'win32console'
6
- gem 'minitest-reporters'
10
+ if RUBY_PLATFORM =~ /(win32|mingw)/
11
+ gem "win32console"
12
+ end
13
+ gem "minitest-reporters"
7
14
  require 'minitest/reporters'
8
- MiniTest::Unit.runner = MiniTest::SuiteRunner.new
9
- MiniTest::Unit.runner.reporters << MiniTest::Reporters::RubyMineReporter.new
15
+ MiniTest::Reporters.use!
10
16
  end
11
17
 
12
18
  # To make testing/debugging easier, test within this source tree versus an installed gem
13
-
14
19
  dir = File.dirname(__FILE__)
15
20
  root = File.expand_path(File.join(dir, '..'))
16
21
  lib = File.expand_path(File.join(root, 'lib'))
@@ -71,11 +76,26 @@ module RubyProf
71
76
  goodbye
72
77
  end
73
78
  end
74
-
75
- if RUBY_VERSION < '1.9'
76
- PARENT = Object
77
- else
78
- PARENT = BasicObject
79
+
80
+ def self.ruby_major_version
81
+ match = RUBY_VERSION.match(/(\d)\.(\d)/)
82
+ return Integer(match[1])
79
83
  end
80
84
 
85
+ def self.ruby_minor_version
86
+ match = RUBY_VERSION.match(/(\d)\.(\d)/)
87
+ return Integer(match[2])
88
+ end
89
+
90
+ def self.parent_object
91
+ if ruby_major_version == 1 && ruby_minor_version == 8
92
+ Object
93
+ else
94
+ BasicObject
95
+ end
96
+ end
97
+
98
+ def self.ruby_2?
99
+ ruby_major_version == 2
100
+ end
81
101
  end