method_info 0.1.3 → 0.1.4

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.
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