@@ -210,40 +210,58 @@ all refinements from the same module are active when a refined method
210210
211211== Method Lookup
212212
213- When looking up a method for an instance of class +C+ Ruby checks:
213+ Method lookup in Ruby is based on the ancestor chain. You can see the
214+ ancestor chain for any object in Ruby by doing:
214215
215- * The refinements of +C+, in reverse order of activation
216- * The prepended modules of +C+
217- * +C+
218- * The included modules of +C+
216+ object.singleton_class.ancestors
217+ # or, if the object does not support a singleton class:
218+ object.class.ancestors
219219
220- If no method was found at any point this repeats with the superclass of +C+.
220+ The ancestor chain is constructed as follows:
221221
222- Note that methods in a subclass have priority over refinements in a
223- superclass. For example, if the method <code>/</code> is defined in a
224- refinement for Numeric <code>1 / 2</code> invokes the original Integer#/
225- because Integer is a subclass of Numeric and is searched before the refinements
226- for the superclass Numeric. Since the method <code>/</code> is also present
227- in child +Integer+, the method lookup does not move up to the superclass.
222+ * Subclasses are before superclasses in the ancestor chain
223+ * Prepended modules are before the class they prepend in the ancestor
224+ chain, in reverse order in which they were prepended.
225+ * Included modules are after the class they are included in in the
226+ ancestor chain, in reverse order in which they were included.
227+
228+ When looking up a method for an object, Ruby goes through each ancestor:
229+
230+ * If the class/module has been refined, Ruby will consider the refinements
231+ activated at the point the method was called, in reverse order of
232+ activation.
233+ * Otherwise, Ruby will check the methods of the class/module itself.
234+
235+ If no method was found at either point this repeats with the next
236+ ancestor.
228237
229- However, if a method +foo+ is defined on Numeric in a refinement, <code>1.foo</code>
238+ Note that methods in a earlier ancestor have priority over refinements in a
239+ later ancestor. For example, if the method <code>/</code> is defined in a
240+ refinement for Numeric <code>1 / 2</code> invokes the original Integer#/
241+ because Integer is a comes before Numeric in the ancestor chain. However,
242+ if a method +foo+ is defined on Numeric in a refinement, <code>1.foo</code>
230243invokes that method since +foo+ does not exist on Integer.
231244
232245== +super+
233246
234- When +super+ is invoked method lookup checks:
247+ When +super+ is invoked, method lookup starts:
248+
249+ * If the method is in a refinement, at the refined class or module
250+ * Otherwise, at the next ancestor
251+
252+ Method lookup then proceeds as described in the Method Lookup section
253+ above.
235254
236- * The included modules of the current class. Note that the current class may
237- be a refinement.
238- * If the current class is a refinement, the method lookup proceeds as in the
239- Method Lookup section above.
240- * If the current class has a direct superclass, the method proceeds as in the
241- Method Lookup section above using the superclass .
255+ Refinements activated at the call site of a refinement method do not
256+ affect +super+ inside that method. Only refinements activated at the
257+ point +super+ was called affect method lookup for that +super+ call.
258+ You cannot use refinements to insert into the middle of a method
259+ lookup chain, only to insert at the start of a method lookup chain,
260+ unless you control the +super+ call sites .
242261
243- Note that +super+ in a method of a refinement invokes the method in the
244- refined class even if there is another refinement which has been activated in
245- the same context. This is only true for +super+ in a method of a refinement, it
246- does not apply to +super+ in a method in a module that is included in a refinement.
262+ Note that if you refine a module, the refinement method can call +super+
263+ to call the method in the module, but the method in the module cannot
264+ call +super+ to continue the method lookup process to further ancestors.
247265
248266== Methods Introspection
249267
0 commit comments