From: "shugo (Shugo Maeda)" Date: 2012-11-05T12:16:09+09:00 Subject: [ruby-core:48872] [ruby-trunk - Bug #7269] Refinement doesn't work if using locate after method Issue #7269 has been updated by shugo (Shugo Maeda). headius (Charles Nutter) wrote: > I commented on the other bug about how refinements need to be temporal > to limit their impact (implementation-wise), but there are obvious > flaws in making them temporal too. Your example above shows how > ordering can change what method will be called. My example was using > calls that happen up-hierarchy in different files. > > Even if we ignore implementation/performance concerns (and there are > lots of them), there are many behavioral problems like this with > refinements. I've started to wonder if it's better to limit refinements based on modules instead of lexical scopes. In the current implementation a cref has a table for activated refinements, but in module-based refinements a module linked from the cref have the table. Furthermore, in the current implementation the table is shared and copied-on-write by nested crefs, but it may be better to separate them and search refinements in outer modules when a method is not found in the table of the current module. For example, modue Foo using X # Foo's table has refinements in X. module Bar using Y # Bar's table has refinements in Y, not X. C.new.foo # First, Bar's table is searched, then Foo's table is searched. end end In module-based refinements, toplevel using should affects not only the current file, but global. ---------------------------------------- Bug #7269: Refinement doesn't work if using locate after method https://bugs.ruby-lang.org/issues/7269#change-32361 Author: ko1 (Koichi Sasada) Status: Open Priority: Normal Assignee: shugo (Shugo Maeda) Category: core Target version: 2.0.0 ruby -v: ruby 2.0.0dev (2012-11-01 trunk 37404) [i386-mswin32_100] Refinement doesn't work if using locate after method. (I eliminate discussion because my laptop doesn't have enough power...) class C def foo p :C_foo end end module M1 refine C do def foo p :M1_foo super end end end module M2 refine C do def foo p :M2_foo super end end end class D using M1 def x C.new.foo end using M2 end p :x D.new.x #=> :x :M1_foo :C_foo -- http://bugs.ruby-lang.org/