method_extensions 0.0.1 → 0.0.2

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.
@@ -5,211 +5,213 @@ rescue LoadError
5
5
  ripper_available = false
6
6
  end
7
7
 
8
- module MethodSourceWithDoc
9
- # Returns method source by parsing the file returned by `Method#source_location`.
10
- #
11
- # If method definition cannot be found `ArgumentError` exception is raised
12
- # (this includes methods defined `attr_accessor`, `module_eval` etc.).
13
- #
14
- # Sample IRB session:
15
- #
16
- # ruby-1.9.2-head > require 'fileutils'
17
- #
18
- # ruby-1.9.2-head > puts FileUtils.method(:mkdir).source
19
- # def mkdir(list, options = {})
20
- # fu_check_options options, OPT_TABLE['mkdir']
21
- # list = fu_list(list)
22
- # fu_output_message "mkdir #{options[:mode] ? ('-m %03o ' % options[:mode]) : ''}#{list.join ' '}" if options[:verbose]
23
- # return if options[:noop]
24
- #
25
- # list.each do |dir|
26
- # fu_mkdir dir, options[:mode]
27
- # end
28
- # end
29
- # => nil
30
- def source
31
- MethodSourceRipper.source_from_source_location(source_location)
32
- end
33
-
34
- # Returns comment preceding the method definition by parsing the file
35
- # returned by `Method#source_location`
36
- #
37
- # Sample IRB session:
38
- #
39
- # ruby-1.9.2-head > require 'fileutils'
40
- #
41
- # ruby-1.9.2-head > puts FileUtils.method(:mkdir).doc
42
- # #
43
- # # Options: mode noop verbose
44
- # #
45
- # # Creates one or more directories.
46
- # #
47
- # # FileUtils.mkdir 'test'
48
- # # FileUtils.mkdir %w( tmp data )
49
- # # FileUtils.mkdir 'notexist', :noop => true # Does not really create.
50
- # # FileUtils.mkdir 'tmp', :mode => 0700
51
- # #
52
- def doc
53
- MethodDocRipper.doc_from_source_location(source_location)
54
- end
8
+ module MethodExtensions
9
+ module MethodSourceWithDoc
10
+ # Returns method source by parsing the file returned by `Method#source_location`.
11
+ #
12
+ # If method definition cannot be found `ArgumentError` exception is raised
13
+ # (this includes methods defined `attr_accessor`, `module_eval` etc.).
14
+ #
15
+ # Sample IRB session:
16
+ #
17
+ # ruby-1.9.2-head > require 'fileutils'
18
+ #
19
+ # ruby-1.9.2-head > puts FileUtils.method(:mkdir).source
20
+ # def mkdir(list, options = {})
21
+ # fu_check_options options, OPT_TABLE['mkdir']
22
+ # list = fu_list(list)
23
+ # fu_output_message "mkdir #{options[:mode] ? ('-m %03o ' % options[:mode]) : ''}#{list.join ' '}" if options[:verbose]
24
+ # return if options[:noop]
25
+ #
26
+ # list.each do |dir|
27
+ # fu_mkdir dir, options[:mode]
28
+ # end
29
+ # end
30
+ # => nil
31
+ def source
32
+ MethodSourceRipper.source_from_source_location(source_location)
33
+ end
55
34
 
56
- # ruby-1.9.2-head > irb_context.inspect_mode = false # turn off inspect mode so that we can view sources
57
- #
58
- # ruby-1.9.2-head > ActiveRecord::Base.method(:find).source_with_doc
59
- # ArgumentError: failed to find method definition around the lines:
60
- # delegate :find, :first, :last, :all, :destroy, :destroy_all, :exists?, :delete, :delete_all, :update, :update_all, :to => :scoped
61
- # delegate :find_each, :find_in_batches, :to => :scoped
62
- #
63
- # ruby-1.9.2-head > ActiveRecord::Base.method(:scoped).source_with_doc
64
- # # Returns an anonymous scope.
65
- # #
66
- # # posts = Post.scoped
67
- # # posts.size # Fires "select count(*) from posts" and returns the count
68
- # # posts.each {|p| puts p.name } # Fires "select * from posts" and loads post objects
69
- # #
70
- # # fruits = Fruit.scoped
71
- # # fruits = fruits.where(:colour => 'red') if options[:red_only]
72
- # # fruits = fruits.limit(10) if limited?
73
- # #
74
- # # Anonymous \scopes tend to be useful when procedurally generating complex queries, where passing
75
- # # intermediate values (scopes) around as first-class objects is convenient.
76
- # #
77
- # # You can define a scope that applies to all finders using ActiveRecord::Base.default_scope.
78
- # def scoped(options = {}, &block)
79
- # if options.present?
80
- # relation = scoped.apply_finder_options(options)
81
- # block_given? ? relation.extending(Module.new(&block)) : relation
82
- # else
83
- # current_scoped_methods ? unscoped.merge(current_scoped_methods) : unscoped.clone
84
- # end
85
- # end
86
- #
87
- # ruby-1.9.2-head > ActiveRecord::Base.method(:unscoped).source_with_doc
88
- # => def unscoped
89
- # @unscoped ||= Relation.new(self, arel_table)
90
- # finder_needs_type_condition? ? @unscoped.where(type_condition) : @unscoped
91
- # end
92
- #
93
- # ruby-1.9.2-head > ActiveRecord::Relation.instance_method(:find).source_with_doc
94
- # => # Find operates with four different retrieval approaches:
95
- # ...
96
- # def find(*args, &block)
97
- # return to_a.find(&block) if block_given?
98
- #
99
- # options = args.extract_options!
100
- #
101
- # if options.present?
102
- # ...
103
- def source_with_doc
104
- return unless source_location
105
-
106
- [doc.to_s.chomp, source_unindent(source)].compact.reject(&:empty?).join("\n")
107
- end
35
+ # Returns comment preceding the method definition by parsing the file
36
+ # returned by `Method#source_location`
37
+ #
38
+ # Sample IRB session:
39
+ #
40
+ # ruby-1.9.2-head > require 'fileutils'
41
+ #
42
+ # ruby-1.9.2-head > puts FileUtils.method(:mkdir).doc
43
+ # #
44
+ # # Options: mode noop verbose
45
+ # #
46
+ # # Creates one or more directories.
47
+ # #
48
+ # # FileUtils.mkdir 'test'
49
+ # # FileUtils.mkdir %w( tmp data )
50
+ # # FileUtils.mkdir 'notexist', :noop => true # Does not really create.
51
+ # # FileUtils.mkdir 'tmp', :mode => 0700
52
+ # #
53
+ def doc
54
+ MethodDocRipper.doc_from_source_location(source_location)
55
+ end
108
56
 
109
- def full_inspect
110
- "#{ inspect }\n#{ source_location }\n#{ source_with_doc }"
111
- end
57
+ # ruby-1.9.2-head > irb_context.inspect_mode = false # turn off inspect mode so that we can view sources
58
+ #
59
+ # ruby-1.9.2-head > ActiveRecord::Base.method(:find).source_with_doc
60
+ # ArgumentError: failed to find method definition around the lines:
61
+ # delegate :find, :first, :last, :all, :destroy, :destroy_all, :exists?, :delete, :delete_all, :update, :update_all, :to => :scoped
62
+ # delegate :find_each, :find_in_batches, :to => :scoped
63
+ #
64
+ # ruby-1.9.2-head > ActiveRecord::Base.method(:scoped).source_with_doc
65
+ # # Returns an anonymous scope.
66
+ # #
67
+ # # posts = Post.scoped
68
+ # # posts.size # Fires "select count(*) from posts" and returns the count
69
+ # # posts.each {|p| puts p.name } # Fires "select * from posts" and loads post objects
70
+ # #
71
+ # # fruits = Fruit.scoped
72
+ # # fruits = fruits.where(:colour => 'red') if options[:red_only]
73
+ # # fruits = fruits.limit(10) if limited?
74
+ # #
75
+ # # Anonymous \scopes tend to be useful when procedurally generating complex queries, where passing
76
+ # # intermediate values (scopes) around as first-class objects is convenient.
77
+ # #
78
+ # # You can define a scope that applies to all finders using ActiveRecord::Base.default_scope.
79
+ # def scoped(options = {}, &block)
80
+ # if options.present?
81
+ # relation = scoped.apply_finder_options(options)
82
+ # block_given? ? relation.extending(Module.new(&block)) : relation
83
+ # else
84
+ # current_scoped_methods ? unscoped.merge(current_scoped_methods) : unscoped.clone
85
+ # end
86
+ # end
87
+ #
88
+ # ruby-1.9.2-head > ActiveRecord::Base.method(:unscoped).source_with_doc
89
+ # => def unscoped
90
+ # @unscoped ||= Relation.new(self, arel_table)
91
+ # finder_needs_type_condition? ? @unscoped.where(type_condition) : @unscoped
92
+ # end
93
+ #
94
+ # ruby-1.9.2-head > ActiveRecord::Relation.instance_method(:find).source_with_doc
95
+ # => # Find operates with four different retrieval approaches:
96
+ # ...
97
+ # def find(*args, &block)
98
+ # return to_a.find(&block) if block_given?
99
+ #
100
+ # options = args.extract_options!
101
+ #
102
+ # if options.present?
103
+ # ...
104
+ def source_with_doc
105
+ return unless source_location
112
106
 
113
- private
107
+ [doc.to_s.chomp, source_unindent(source)].compact.reject(&:empty?).join("\n")
108
+ end
114
109
 
115
- def source_unindent(src)
116
- lines = src.split("\n")
117
- indented_lines = lines[1 .. -1] # first line doesn't have proper indentation
118
- indent_level = indented_lines.
119
- reject { |line| line.strip.empty? }. # exclude empty lines from indent level calculation
120
- map { |line| line[/^(\s*)/, 1].size }. # map to indent level of every line
121
- min
122
- [lines[0], *indented_lines.map { |line| line[indent_level .. -1] }].join("\n")
123
- end
124
-
125
- class ::Method
126
- include MethodSourceWithDoc
127
- end
110
+ def full_inspect
111
+ "#{ inspect }\n#{ source_location }\n#{ source_with_doc }"
112
+ end
128
113
 
129
- class ::UnboundMethod
130
- include MethodSourceWithDoc
131
- end
114
+ private
132
115
 
133
- class MethodSourceRipper < Ripper
134
- def self.source_from_source_location(source_location)
135
- return unless source_location
136
- new(*source_location).method_source
116
+ def source_unindent(src)
117
+ lines = src.split("\n")
118
+ indented_lines = lines[1 .. -1] # first line doesn't have proper indentation
119
+ indent_level = indented_lines.
120
+ reject { |line| line.strip.empty? }. # exclude empty lines from indent level calculation
121
+ map { |line| line[/^(\s*)/, 1].size }. # map to indent level of every line
122
+ min
123
+ [lines[0], *indented_lines.map { |line| line[indent_level .. -1] }].join("\n")
137
124
  end
138
125
 
139
- def initialize(filename, method_definition_lineno)
140
- super(IO.read(filename), filename)
141
- @src_lines = IO.read(filename).split("\n")
142
- @method_definition_lineno = method_definition_lineno
126
+ class ::Method
127
+ include MethodSourceWithDoc
143
128
  end
144
129
 
145
- def method_source
146
- parse
147
- if @method_source
148
- @method_source
149
- else
150
- raise ArgumentError.new("failed to find method definition around the lines:\n" <<
151
- definition_lines.join("\n"))
152
- end
130
+ class ::UnboundMethod
131
+ include MethodSourceWithDoc
153
132
  end
154
133
 
155
- def definition_lines
156
- @src_lines[@method_definition_lineno - 1 .. @method_definition_lineno + 1]
157
- end
134
+ class MethodSourceRipper < Ripper
135
+ def self.source_from_source_location(source_location)
136
+ return unless source_location
137
+ new(*source_location).method_source
138
+ end
158
139
 
159
- Ripper::SCANNER_EVENTS.each do |meth|
160
- define_method("on_#{ meth }") do |*args|
161
- [lineno, column]
140
+ def initialize(filename, method_definition_lineno)
141
+ super(IO.read(filename), filename)
142
+ @src_lines = IO.read(filename).split("\n")
143
+ @method_definition_lineno = method_definition_lineno
162
144
  end
163
- end
164
145
 
165
- def on_def(name, params, body)
166
- from_lineno, from_column = name
167
- return unless @method_definition_lineno == from_lineno
146
+ def method_source
147
+ parse
148
+ if @method_source
149
+ @method_source
150
+ else
151
+ raise ArgumentError.new("failed to find method definition around the lines:\n" <<
152
+ definition_lines.join("\n"))
153
+ end
154
+ end
168
155
 
169
- to_lineno, to_column = lineno, column
156
+ def definition_lines
157
+ @src_lines[@method_definition_lineno - 1 .. @method_definition_lineno + 1]
158
+ end
170
159
 
171
- @method_source = @src_lines[from_lineno - 1 .. to_lineno - 1].join("\n").strip
172
- end
160
+ Ripper::SCANNER_EVENTS.each do |meth|
161
+ define_method("on_#{ meth }") do |*args|
162
+ [lineno, column]
163
+ end
164
+ end
173
165
 
174
- def on_defs(target, period, name, params, body)
175
- on_def(target, params, body)
176
- end
177
- end
166
+ def on_def(name, params, body)
167
+ from_lineno, from_column = name
168
+ return unless @method_definition_lineno == from_lineno
178
169
 
179
- class MethodDocRipper < Ripper
180
- def self.doc_from_source_location(source_location)
181
- return unless source_location
182
- new(*source_location).method_doc
183
- end
170
+ to_lineno, to_column = lineno, column
184
171
 
185
- def initialize(filename, method_definition_lineno)
186
- super(IO.read(filename), filename)
187
- @method_definition_lineno = method_definition_lineno
188
- @last_comment_block = nil
189
- end
172
+ @method_source = @src_lines[from_lineno - 1 .. to_lineno - 1].join("\n").strip
173
+ end
190
174
 
191
- def method_doc
192
- parse
193
- @method_doc
175
+ def on_defs(target, period, name, params, body)
176
+ on_def(target, params, body)
177
+ end
194
178
  end
195
179
 
196
- Ripper::SCANNER_EVENTS.each do |meth|
197
- define_method("on_#{ meth }") do |token|
198
- if @last_comment_block &&
199
- lineno == @method_definition_lineno
200
- @method_doc = @last_comment_block.join.gsub(/^\s*/, "")
201
- end
180
+ class MethodDocRipper < Ripper
181
+ def self.doc_from_source_location(source_location)
182
+ return unless source_location
183
+ new(*source_location).method_doc
184
+ end
202
185
 
186
+ def initialize(filename, method_definition_lineno)
187
+ super(IO.read(filename), filename)
188
+ @method_definition_lineno = method_definition_lineno
203
189
  @last_comment_block = nil
204
190
  end
205
- end
206
191
 
207
- def on_comment(token)
208
- (@last_comment_block ||= []) << token
209
- end
192
+ def method_doc
193
+ parse
194
+ @method_doc
195
+ end
196
+
197
+ Ripper::SCANNER_EVENTS.each do |meth|
198
+ define_method("on_#{ meth }") do |token|
199
+ if @last_comment_block &&
200
+ lineno == @method_definition_lineno
201
+ @method_doc = @last_comment_block.join.gsub(/^\s*/, "")
202
+ end
203
+
204
+ @last_comment_block = nil
205
+ end
206
+ end
210
207
 
211
- def on_sp(token)
212
- @last_comment_block << token if @last_comment_block
208
+ def on_comment(token)
209
+ (@last_comment_block ||= []) << token
210
+ end
211
+
212
+ def on_sp(token)
213
+ @last_comment_block << token if @last_comment_block
214
+ end
213
215
  end
214
216
  end
215
- end if ripper_available
217
+ end if ripper_available
@@ -1,273 +1,274 @@
1
- module MethodSuper
2
- # Returns method which will be called if given Method/UnboundMethod would
3
- # call `super`.
4
- # Implementation is incomplete with regard to modules included in singleton
5
- # class (`class C; extend M; end`), but such modules usually don't use `super`
6
- # anyway.
7
- #
8
- # Examples
9
- #
10
- # class Base
11
- # def meth; end
12
- # end
13
- #
14
- # class Derived < Base
15
- # def meth; end
16
- # end
17
- #
18
- # ruby-1.9.2-head > Derived.instance_method(:meth)
19
- # => #<UnboundMethod: Derived#meth>
20
- #
21
- # ruby-1.9.2-head > Derived.instance_method(:meth).super
22
- # => #<UnboundMethod: Base#meth>
23
- def super
24
- raise ArgumentError, "method doesn't have required @context_for_super instance variable set" unless @context_for_super
25
-
26
- klass, level, name = @context_for_super.values_at(:klass, :level, :name)
27
-
28
- unless @methods_all
29
- @methods_all = MethodSuper.methods_all(klass)
30
-
31
- # on first call ignore first found method
1
+ module MethodExtensions
2
+ module MethodSuper
3
+ # Returns method which will be called if given Method/UnboundMethod would
4
+ # call `super`.
5
+ # Implementation is incomplete with regard to modules included in singleton
6
+ # class (`class C; extend M; end`), but such modules usually don't use `super`
7
+ # anyway.
8
+ #
9
+ # Examples
10
+ #
11
+ # class Base
12
+ # def meth; end
13
+ # end
14
+ #
15
+ # class Derived < Base
16
+ # def meth; end
17
+ # end
18
+ #
19
+ # ruby-1.9.2-head > Derived.instance_method(:meth)
20
+ # => #<UnboundMethod: Derived#meth>
21
+ #
22
+ # ruby-1.9.2-head > Derived.instance_method(:meth).super
23
+ # => #<UnboundMethod: Base#meth>
24
+ def super
25
+ raise ArgumentError, "method doesn't have required @context_for_super instance variable set" unless @context_for_super
26
+
27
+ klass, level, name = @context_for_super.values_at(:klass, :level, :name)
28
+
29
+ unless @methods_all
30
+ @methods_all = MethodSuper.methods_all(klass)
31
+
32
+ # on first call ignore first found method
33
+ superclass_index = MethodSuper.superclass_index(@methods_all,
34
+ level,
35
+ name)
36
+ @methods_all = @methods_all[superclass_index + 1 .. -1]
37
+
38
+ end
39
+
32
40
  superclass_index = MethodSuper.superclass_index(@methods_all,
33
41
  level,
34
42
  name)
35
- @methods_all = @methods_all[superclass_index + 1 .. -1]
36
-
37
- end
38
43
 
39
- superclass_index = MethodSuper.superclass_index(@methods_all,
40
- level,
41
- name)
44
+ superclass = @methods_all[superclass_index].keys.first
45
+ rest_methods_all = @methods_all[superclass_index + 1 .. -1]
42
46
 
43
- superclass = @methods_all[superclass_index].keys.first
44
- rest_methods_all = @methods_all[superclass_index + 1 .. -1]
47
+ super_method = if level == :class && superclass.class == Class
48
+ superclass.method(name)
49
+ elsif level == :instance ||
50
+ (level == :class && superclass.class == Module)
51
+ superclass.instance_method(name)
52
+ end
45
53
 
46
- super_method = if level == :class && superclass.class == Class
47
- superclass.method(name)
48
- elsif level == :instance ||
49
- (level == :class && superclass.class == Module)
50
- superclass.instance_method(name)
54
+ super_method.instance_variable_set(:@context_for_super, @context_for_super)
55
+ super_method.instance_variable_set(:@methods_all, rest_methods_all)
56
+ super_method
51
57
  end
52
58
 
53
- super_method.instance_variable_set(:@context_for_super, @context_for_super)
54
- super_method.instance_variable_set(:@methods_all, rest_methods_all)
55
- super_method
56
- end
57
-
58
- private
59
+ private
59
60
 
60
- def self.superclass_index(methods_all, level, name)
61
- methods_all.index do |ancestor_with_methods|
62
- ancestor, methods =
63
- ancestor_with_methods.keys.first, ancestor_with_methods.values.first
64
- methods[level] && methods[level].any? do |level, methods|
65
- methods.include?(name)
61
+ def self.superclass_index(methods_all, level, name)
62
+ methods_all.index do |ancestor_with_methods|
63
+ ancestor, methods =
64
+ ancestor_with_methods.keys.first, ancestor_with_methods.values.first
65
+ methods[level] && methods[level].any? do |level, methods|
66
+ methods.include?(name)
67
+ end
66
68
  end
67
69
  end
68
- end
69
70
 
70
- def self.methods_all(klass)
71
- MethodSuper::Methods.new(klass, :ancestor_name_formatter => proc { |ancestor, _| ancestor }).all
72
- end
73
-
74
- class Methods
75
- def initialize(klass_or_module, options = {})
76
- @klass_or_module = klass_or_module
77
- @ancestor_name_formatter = options.fetch(:ancestor_name_formatter,
78
- default_ancestor_name_formatter)
79
- @exclude_trite = options.fetch(:exclude_trite, true)
71
+ def self.methods_all(klass)
72
+ MethodSuper::Methods.new(klass, :ancestor_name_formatter => proc { |ancestor, _| ancestor }).all
80
73
  end
81
74
 
82
- def all
83
- @all ||= find_all
84
- end
75
+ class Methods
76
+ def initialize(klass_or_module, options = {})
77
+ @klass_or_module = klass_or_module
78
+ @ancestor_name_formatter = options.fetch(:ancestor_name_formatter,
79
+ default_ancestor_name_formatter)
80
+ @exclude_trite = options.fetch(:exclude_trite, true)
81
+ end
82
+
83
+ def all
84
+ @all ||= find_all
85
+ end
85
86
 
86
- VISIBILITIES = [ :public, :protected, :private ].freeze
87
+ VISIBILITIES = [ :public, :protected, :private ].freeze
87
88
 
88
- protected
89
+ protected
89
90
 
90
- def default_ancestor_name_formatter
91
- proc do |ancestor, singleton|
92
- ancestor_name(ancestor, singleton)
91
+ def default_ancestor_name_formatter
92
+ proc do |ancestor, singleton|
93
+ ancestor_name(ancestor, singleton)
94
+ end
93
95
  end
94
- end
95
96
 
96
- def find_all
97
- ancestors = [] # flattened ancestors (both normal and singleton)
97
+ def find_all
98
+ ancestors = [] # flattened ancestors (both normal and singleton)
98
99
 
99
- (@klass_or_module.ancestors - trite_ancestors).each do |ancestor|
100
- ancestor_singleton = ancestor.singleton_class
100
+ (@klass_or_module.ancestors - trite_ancestors).each do |ancestor|
101
+ ancestor_singleton = ancestor.singleton_class
101
102
 
102
- # Modules don't inherit class methods from included modules
103
- unless @klass_or_module.instance_of?(Module) && ancestor != @klass_or_module
104
- class_methods = collect_instance_methods(ancestor_singleton)
105
- end
103
+ # Modules don't inherit class methods from included modules
104
+ unless @klass_or_module.instance_of?(Module) && ancestor != @klass_or_module
105
+ class_methods = collect_instance_methods(ancestor_singleton)
106
+ end
106
107
 
107
- instance_methods = collect_instance_methods(ancestor)
108
+ instance_methods = collect_instance_methods(ancestor)
108
109
 
109
- append_ancestor_entry(ancestors, @ancestor_name_formatter[ancestor, false],
110
- class_methods, instance_methods)
110
+ append_ancestor_entry(ancestors, @ancestor_name_formatter[ancestor, false],
111
+ class_methods, instance_methods)
111
112
 
112
- (singleton_ancestors(ancestor) || []).each do |singleton_ancestor|
113
- class_methods = collect_instance_methods(singleton_ancestor)
114
- append_ancestor_entry(ancestors, @ancestor_name_formatter[singleton_ancestor, true],
115
- class_methods)
113
+ (singleton_ancestors(ancestor) || []).each do |singleton_ancestor|
114
+ class_methods = collect_instance_methods(singleton_ancestor)
115
+ append_ancestor_entry(ancestors, @ancestor_name_formatter[singleton_ancestor, true],
116
+ class_methods)
117
+ end
116
118
  end
117
- end
118
119
 
119
- ancestors
120
- end
120
+ ancestors
121
+ end
121
122
 
122
- # singleton ancestors which ancestor introduced
123
- def singleton_ancestors(ancestor)
124
- @singleton_ancestors ||= all_singleton_ancestors
125
- @singleton_ancestors[ancestor]
126
- end
123
+ # singleton ancestors which ancestor introduced
124
+ def singleton_ancestors(ancestor)
125
+ @singleton_ancestors ||= all_singleton_ancestors
126
+ @singleton_ancestors[ancestor]
127
+ end
127
128
 
128
- def all_singleton_ancestors
129
- all = {}
130
- seen = []
131
- (@klass_or_module.ancestors - trite_ancestors).reverse.each do |ancestor|
132
- singleton_ancestors = ancestor.singleton_class.ancestors - trite_singleton_ancestors
133
- introduces = singleton_ancestors - seen
134
- all[ancestor] = introduces unless introduces.empty?
135
- seen.concat singleton_ancestors
129
+ def all_singleton_ancestors
130
+ all = {}
131
+ seen = []
132
+ (@klass_or_module.ancestors - trite_ancestors).reverse.each do |ancestor|
133
+ singleton_ancestors = ancestor.singleton_class.ancestors - trite_singleton_ancestors
134
+ introduces = singleton_ancestors - seen
135
+ all[ancestor] = introduces unless introduces.empty?
136
+ seen.concat singleton_ancestors
137
+ end
138
+ all
136
139
  end
137
- all
138
- end
139
140
 
140
- def ancestor_name(ancestor, singleton)
141
- "#{ singleton ? "S" : ""}[#{ ancestor.is_a?(Class) ? "C" : "M" }] #{ ancestor.name || ancestor.to_s }"
142
- end
141
+ def ancestor_name(ancestor, singleton)
142
+ "#{ singleton ? "S" : ""}[#{ ancestor.is_a?(Class) ? "C" : "M" }] #{ ancestor.name || ancestor.to_s }"
143
+ end
143
144
 
144
- # ancestor is included only when contributes some methods
145
- def append_ancestor_entry(ancestors, ancestor, class_methods, instance_methods = nil)
146
- if class_methods || instance_methods
147
- ancestor_entry = {}
148
- ancestor_entry[:class] = class_methods if class_methods
149
- ancestor_entry[:instance] = instance_methods if instance_methods
150
- ancestors << {ancestor => ancestor_entry}
145
+ # ancestor is included only when contributes some methods
146
+ def append_ancestor_entry(ancestors, ancestor, class_methods, instance_methods = nil)
147
+ if class_methods || instance_methods
148
+ ancestor_entry = {}
149
+ ancestor_entry[:class] = class_methods if class_methods
150
+ ancestor_entry[:instance] = instance_methods if instance_methods
151
+ ancestors << {ancestor => ancestor_entry}
152
+ end
151
153
  end
152
- end
153
154
 
154
- # Returns hash { :public => [...public methods...],
155
- # :protected => [...private methods...],
156
- # :private => [...private methods...] }
157
- # keys with empty values are excluded,
158
- # when no methods are found - returns nil
159
- def collect_instance_methods(klass)
160
- methods_with_visibility = VISIBILITIES.map do |visibility|
161
- methods = klass.send("#{ visibility }_instance_methods", false)
162
- [visibility, methods] unless methods.empty?
163
- end.compact
164
- Hash[methods_with_visibility] unless methods_with_visibility.empty?
165
- end
155
+ # Returns hash { :public => [...public methods...],
156
+ # :protected => [...private methods...],
157
+ # :private => [...private methods...] }
158
+ # keys with empty values are excluded,
159
+ # when no methods are found - returns nil
160
+ def collect_instance_methods(klass)
161
+ methods_with_visibility = VISIBILITIES.map do |visibility|
162
+ methods = klass.send("#{ visibility }_instance_methods", false)
163
+ [visibility, methods] unless methods.empty?
164
+ end.compact
165
+ Hash[methods_with_visibility] unless methods_with_visibility.empty?
166
+ end
166
167
 
167
- def trite_singleton_ancestors
168
- return [] unless @exclude_trite
169
- @trite_singleton_ancestors ||= Class.new.singleton_class.ancestors
170
- end
168
+ def trite_singleton_ancestors
169
+ return [] unless @exclude_trite
170
+ @trite_singleton_ancestors ||= Class.new.singleton_class.ancestors
171
+ end
171
172
 
172
- def trite_ancestors
173
- return [] unless @exclude_trite
174
- @trite_ancestors ||= Class.new.ancestors
173
+ def trite_ancestors
174
+ return [] unless @exclude_trite
175
+ @trite_ancestors ||= Class.new.ancestors
176
+ end
175
177
  end
176
178
  end
177
- end
178
-
179
- class Method
180
- include MethodSuper
181
- end
182
179
 
183
- class UnboundMethod
184
- include MethodSuper
185
- end
186
-
187
- class Module
188
- def instance_method_with_ancestors_for_super(name)
189
- method = instance_method_without_ancestors_for_super(name)
190
- method.instance_variable_set(:@context_for_super,
191
- :klass => self,
192
- :level => :instance,
193
- :name => name)
194
-
195
- method
180
+ class ::Method
181
+ include MethodSuper
196
182
  end
197
183
 
198
- unless method_defined?(:instance_method_without_ancestors_for_super) ||
199
- private_method_defined?(:instance_method_without_ancestors_for_super)
200
- alias_method :instance_method_without_ancestors_for_super, :instance_method
201
- alias_method :instance_method, :instance_method_with_ancestors_for_super
184
+ class ::UnboundMethod
185
+ include MethodSuper
202
186
  end
203
- end
204
-
205
- module Kernel
206
- def method_with_ancestors_for_super(name)
207
- method = method_without_ancestors_for_super(name)
208
187
 
209
- if respond_to?(:ancestors)
188
+ class ::Module
189
+ def instance_method_with_ancestors_for_super(name)
190
+ method = instance_method_without_ancestors_for_super(name)
210
191
  method.instance_variable_set(:@context_for_super,
211
192
  :klass => self,
212
- :level => :class,
213
- :name => name)
214
- else
215
- method.instance_variable_set(:@context_for_super,
216
- :klass => self.class,
217
193
  :level => :instance,
218
194
  :name => name)
195
+
196
+ method
219
197
  end
220
-
221
- method
222
- end
223
198
 
224
- unless method_defined?(:method_without_ancestors_for_super) ||
225
- private_method_defined?(:method_without_ancestors_for_super)
226
- alias_method :method_without_ancestors_for_super, :method
227
- alias_method :method, :method_with_ancestors_for_super
199
+ unless method_defined?(:instance_method_without_ancestors_for_super) ||
200
+ private_method_defined?(:instance_method_without_ancestors_for_super)
201
+ alias_method :instance_method_without_ancestors_for_super, :instance_method
202
+ alias_method :instance_method, :instance_method_with_ancestors_for_super
203
+ end
228
204
  end
229
- end
230
205
 
231
- module BaseIncludedModule
232
- def module_meth
233
- end
234
- end
206
+ module ::Kernel
207
+ def method_with_ancestors_for_super(name)
208
+ method = method_without_ancestors_for_super(name)
209
+
210
+ if respond_to?(:ancestors)
211
+ method.instance_variable_set(:@context_for_super,
212
+ :klass => self,
213
+ :level => :class,
214
+ :name => name)
215
+ else
216
+ method.instance_variable_set(:@context_for_super,
217
+ :klass => self.class,
218
+ :level => :instance,
219
+ :name => name)
220
+ end
221
+
222
+ method
223
+ end
235
224
 
236
- module BaseExtendedModule
237
- def module_meth
225
+ unless method_defined?(:method_without_ancestors_for_super) ||
226
+ private_method_defined?(:method_without_ancestors_for_super)
227
+ alias_method :method_without_ancestors_for_super, :method
228
+ alias_method :method, :method_with_ancestors_for_super
229
+ end
238
230
  end
239
231
  end
240
232
 
241
- class BaseClass
242
- include BaseIncludedModule
243
- extend BaseExtendedModule
233
+ if $PROGRAM_NAME == __FILE__
234
+ require "rspec/core"
235
+ require "rspec/expectations"
236
+ require "rspec/matchers"
244
237
 
245
- def self.singleton_meth
238
+ module BaseIncludedModule
239
+ def module_meth
240
+ end
246
241
  end
247
242
 
248
- def meth
243
+ module BaseExtendedModule
244
+ def module_meth
245
+ end
249
246
  end
250
- end
251
247
 
252
- class DerivedClass < BaseClass
253
- def self.singleton_meth
254
- end
248
+ class BaseClass
249
+ include BaseIncludedModule
250
+ extend BaseExtendedModule
255
251
 
256
- def self.module_meth
257
- end
252
+ def self.singleton_meth
253
+ end
258
254
 
259
- def meth
255
+ def meth
256
+ end
260
257
  end
261
258
 
262
- def module_meth
263
- end
264
- end
259
+ class DerivedClass < BaseClass
260
+ def self.singleton_meth
261
+ end
265
262
 
266
- if $PROGRAM_NAME == __FILE__
267
- require "rspec/core"
268
- require "rspec/expectations"
269
- require "rspec/matchers"
263
+ def self.module_meth
264
+ end
265
+
266
+ def meth
267
+ end
270
268
 
269
+ def module_meth
270
+ end
271
+ end
271
272
 
272
273
  describe Method do
273
274
  describe "#super" do
@@ -1,2 +1,3 @@
1
1
  require "method_extensions/method/source_with_doc"
2
- require "method_extensions/method/super"
2
+ # We don't require `super` by default since it patches core methods
3
+ # require "method_extensions/method/super"
@@ -3,7 +3,7 @@ $:.unshift lib unless $:.include?(lib)
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "method_extensions"
6
- s.version = "0.0.1"
6
+ s.version = "0.0.2"
7
7
  s.authors = ["Evgeniy Dolzhenko"]
8
8
  s.email = ["dolzenko@gmail.com"]
9
9
  s.homepage = "http://github.com/dolzenko/method_extensions"
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 1
9
- version: 0.0.1
8
+ - 2
9
+ version: 0.0.2
10
10
  platform: ruby
11
11
  authors:
12
12
  - Evgeniy Dolzhenko
@@ -42,7 +42,6 @@ rdoc_options: []
42
42
  require_paths:
43
43
  - lib
44
44
  required_ruby_version: !ruby/object:Gem::Requirement
45
- none: false
46
45
  requirements:
47
46
  - - ">="
48
47
  - !ruby/object:Gem::Version
@@ -50,7 +49,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
50
49
  - 0
51
50
  version: "0"
52
51
  required_rubygems_version: !ruby/object:Gem::Requirement
53
- none: false
54
52
  requirements:
55
53
  - - ">="
56
54
  - !ruby/object:Gem::Version
@@ -60,7 +58,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
60
58
  requirements: []
61
59
 
62
60
  rubyforge_project:
63
- rubygems_version: 1.3.7
61
+ rubygems_version: 1.3.6
64
62
  signing_key:
65
63
  specification_version: 3
66
64
  summary: Method object extensions for better code navigation