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/