Issue #7269 has been reported by ko1 (Koichi Sasada). ---------------------------------------- Bug #7269: Refinement doesn't work if using locate after method https://bugs.ruby-lang.org/issues/7269 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
on 2012-11-03 01:29
on 2012-11-03 17:13
Issue #7269 has been updated by headius (Charles Nutter). I don't like the idea that using should affect methods already defined. At this point I view using similar to private/protected/etc, which also do not affect methods defined before you call them. ---------------------------------------- Bug #7269: Refinement doesn't work if using locate after method https://bugs.ruby-lang.org/issues/7269#change-32297 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
on 2012-11-03 17:37
(2012/11/03 10:11), headius (Charles Nutter) wrote:
> I don't like the idea that using should affect methods already defined. At this
point I view using similar to private/protected/etc, which also do not affect
methods defined before you call them.
I feel that `using' is similar to `include' and `prepend' rather than
`public' and `private'.
on 2012-11-03 17:43
(2012/11/03 10:36), SASADA Koichi wrote: > (2012/11/03 10:11), headius (Charles Nutter) wrote: >> I don't like the idea that using should affect methods already defined. At this point I view using similar to private/protected/etc, which also do not affect methods defined before you call them. > > I feel that `using' is similar to `include' and `prepend' rather than > `public' and `private'. > The following code (C_User2#x) affect refinement `after' defining method. Is that intentional? ### class C def foo p :C_foo end end module RefineC refine C do def foo p :RefineC_foo super end end end class C_User using RefineC def x C.new.foo end end class C_User2 def x self.class.send(:using, RefineC) C.new.foo end end puts "C.new.foo" C.new.foo puts "C_User.new.x" C_User.new.x puts "C_User2.new.x" C_User2.new.x #=> C.new.foo :C_foo C_User.new.x :RefineC_foo :C_foo C_User2.new.x :RefineC_foo :C_foo
on 2012-11-03 17:46
(2012/11/03 10:42), SASADA Koichi wrote: > def foo > end > C.new.foo > :C_foo > C_User.new.x > :RefineC_foo > :C_foo > C_User2.new.x > :RefineC_foo > :C_foo # is that corner case? :) class C_User2 def x 2.times{ C.new.foo self.class.send(:using, RefineC) } end end
on 2012-11-03 18:04
On Sat, Nov 3, 2012 at 10:45 AM, SASADA Koichi <ko1@atdot.net> wrote: > # is that corner case? :) > > class C_User2 > def x > 2.times{ > C.new.foo > self.class.send(:using, RefineC) > } > end > end 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.
on 2012-11-05 04:16
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
on 2012-11-05 05:11
Issue #7269 has been updated by matz (Yukihiro Matsumoto). OK, I understand the behavior. What are pros and cons of module based refinement? Matz. ---------------------------------------- Bug #7269: Refinement doesn't work if using locate after method https://bugs.ruby-lang.org/issues/7269#change-32362 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
on 2012-11-05 05:43
Issue #7269 has been updated by headius (Charles Nutter).
Making refinements *less* lexical seems like the wrong direction to me.
It means all calls everywhere have to check for refinements all the
time, similar to the module_eval problem.
In the following code:
a.rb:
module Foo
def self.go
C.new.foo
end
end
b.rb:
module Foo
using X
end
I assume that regardless of the order of loading these two files,
calling the "go" method would require searching the refinements table of
Foo, correct? That seems pretty clearly to indicate that module-based
refinements require all call sites everywhere to check for refinements
every time.
----------------------------------------
Bug #7269: Refinement doesn't work if using locate after method
https://bugs.ruby-lang.org/issues/7269#change-32367
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
on 2012-11-05 05:49
Issue #7269 has been updated by headius (Charles Nutter). I should also mention that if we can't tell ahead of time that a call site has to search refinements, it means all calls everywhere will have to have cref available. In JRuby, this could easily be a crippling blow to performance, and in MRI it would make it impossible to eliminate Ruby call frames (or eliminate cref management) ever in the future (which I'm sure ko1 would like to be able to do). Currently JRuby only needs the cref to be available if there's a closure, binding-related call, or constant lookup. We'd now have to make it available 100% of the time. It also means that you will never again be able to look at a piece of code and know if refinements will affect it. Refinements would become one of the most confusing features in Ruby. After talking with Yehuda a bit, I am more and more of the opinion that "using" should only affect call sites lexically in the same scope as (or a child scope of) the "using" call, and only call sites that appear after the "using" call. This would mean having to use "using" in every file where you want refinements active, but it would make it very where refinements are active both to the programmer and to the VM. ---------------------------------------- Bug #7269: Refinement doesn't work if using locate after method https://bugs.ruby-lang.org/issues/7269#change-32368 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
on 2012-11-05 06:49
Issue #7269 has been updated by shugo (Shugo Maeda). matz (Yukihiro Matsumoto) wrote: > OK, I understand the behavior. What are pros and cons of module based refinement? pros: * not affected by the order of loading/using * consistent with module_eval and behavior when a module is reopened (Bug #7271) cons: * might be hard to implement efficiently * especially super when refinements are cascaded might be hard to implement ---------------------------------------- Bug #7269: Refinement doesn't work if using locate after method https://bugs.ruby-lang.org/issues/7269#change-32373 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
on 2012-12-13 06:17
Issue #7269 has been updated by shugo (Shugo Maeda). Status changed from Open to Closed Module#using is removed, so I close this ticket. See https://bugs.ruby-lang.org/projects/ruby-trunk/wik... for scoping of main.using. ---------------------------------------- Bug #7269: Refinement doesn't work if using locate after method https://bugs.ruby-lang.org/issues/7269#change-34689 Author: ko1 (Koichi Sasada) Status: Closed 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
Please log in before posting. Registration is free and takes only a minute.
Existing account
(Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
Log in with Google account | Log in with Yahoo account
No account? Register here.