method_info 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.3
1
+ 0.1.4
@@ -50,7 +50,7 @@ module MethodInfo
50
50
  end
51
51
 
52
52
  def add_method_to_ancestor(method)
53
- ancestor = AncestorMethodStructure.method_owner(@object, method)
53
+ ancestor = method_owner(method)
54
54
  if @ancestors.include?(ancestor)
55
55
  @ancestor_methods[ancestor] << method
56
56
  end
@@ -101,12 +101,34 @@ module MethodInfo
101
101
  end
102
102
 
103
103
  # Returns the class or module where method is defined
104
- def self.method_owner(object, method)
105
- # Printing this warning is not spec'ed: it is only here temporarily until the 1.8.6
106
- # workaround is implemented
107
- STDERR.puts "Ruby >= 1.8.7 required" unless VERSION >= '1.8.7'
108
- object.method(method).owner
104
+ def method_owner(method_symbol)
105
+ method = @object.method(method_symbol)
106
+ method.owner
107
+ rescue
108
+ poor_mans_method_owner(method, method_symbol.to_s)
109
109
  end
110
110
 
111
+ # Ruby 1.8.6 has no Method#owner method, this is a poor man's replacement. It has horrible
112
+ # performance and may break for other ruby implementations than MRI.
113
+ def poor_mans_method_owner(method, method_name)
114
+ # A Method object has no :owner method, but we can infer it's owner from the result of it's
115
+ # :to_s method. Examples:
116
+ # 37.method(:rdiv).to_s => "#<Method: Fixnum#rdiv>"
117
+ # 37.method(:ceil).to_s => "#<Method: Fixnum(Integer)#ceil>"
118
+ # 37.method(:prec).to_s => "#<Method: Fixnum(Precision)#prec>"
119
+ # obj.method(:singleton_method).to_s => "#<Method: #<Object:0x5673b8>.singleton_method>"
120
+ if method.to_s =~ /^#<Method: (.*)[#.]#{Regexp.escape(method_name)}>$/
121
+ owner_string = $1
122
+ # Maybe it is a top level class and we're done
123
+ if owner_string =~ /\w+\((\w+)\)/
124
+ # Module or subclass (like 'Fixnum(Integer)')
125
+ owner_string = $1
126
+ elsif owner_string.include?("#<Object:")
127
+ # probably the eigen class
128
+ owner_string = "#<Class:#{owner_string}>"
129
+ end
130
+ @ancestors.select { |a| a.to_s == owner_string }.first
131
+ end
132
+ end
111
133
  end
112
134
  end
@@ -11,5 +11,69 @@ module MethodInfo
11
11
  it "should print the methods on an object" do
12
12
  end
13
13
  end
14
+
15
+ describe "method_owner" do
16
+ it "gets the method from the object" do
17
+ obj = Object.new
18
+ obj.should_receive(:method).with(:to_s).and_return(mock('method', :owner => nil))
19
+ ams = AncestorMethodStructure.new(obj,
20
+ :ancestors_to_show => [],
21
+ :ancestors_to_exclude => [])
22
+ ams.send(:method_owner, :to_s)
23
+ end
24
+
25
+ describe "for ruby >= 1.8.7" do
26
+ it "gets the owner of the method and returns it" do
27
+ obj = mock('object')
28
+ mock_method = mock('method')
29
+ obj.stub!(:method).and_return(mock_method)
30
+ mock_method.should_receive(:owner).and_return :foo
31
+ ams = AncestorMethodStructure.new(obj,
32
+ :ancestors_to_show => [],
33
+ :ancestors_to_exclude => [])
34
+ ams.send(:method_owner, :to_s).should == :foo
35
+ end
36
+ end
37
+
38
+ describe "for ruby 1.8.6" do
39
+ it "should use the poor_mans_method_owner" do
40
+ obj = mock('object')
41
+ mock_method = mock('method', :to_s => 'mock_method_name')
42
+ obj.stub!(:method).and_return(mock_method)
43
+ mock_method.stub!(:owner).and_raise NameError
44
+ ams = AncestorMethodStructure.new(obj,
45
+ :ancestors_to_show => [],
46
+ :ancestors_to_exclude => [])
47
+ ams.should_receive(:poor_mans_method_owner).with(mock_method, "to_i")
48
+ ams.send(:method_owner, :to_i)
49
+ end
50
+
51
+ describe "poor_mans_method_owner" do
52
+ it "finds the owner if it is the base clas" do
53
+ ams = AncestorMethodStructure.new(37, {})
54
+ ams.send(:poor_mans_method_owner, 37.method(:rdiv), "rdiv").should == Fixnum
55
+ end
56
+
57
+ it "finds the owner if it is a super clas" do
58
+ ams = AncestorMethodStructure.new(37, {})
59
+ ams.send(:poor_mans_method_owner, 37.method(:ceil), "ceil").should == Integer
60
+ end
61
+
62
+ it "finds the owner if it is a module" do
63
+ ams = AncestorMethodStructure.new(37, {})
64
+ ams.send(:poor_mans_method_owner, 37.method(:prec), "prec").should == Precision
65
+ end
66
+
67
+ it "finds the owner if it is the eigenclass" do
68
+ obj = Object.new
69
+ def obj.foo
70
+ :foo
71
+ end
72
+ ams = AncestorMethodStructure.new(obj, :singleton_methods => true)
73
+ ams.send(:poor_mans_method_owner, obj.method(:foo), "foo").should == class << obj; self; end
74
+ end
75
+ end
76
+ end
77
+ end
14
78
  end
15
79
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: method_info
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tom ten Thij