From: ko1@...
Date: 2015-05-28T09:57:47+00:00
Subject: [ruby-core:69392] [Ruby trunk - Bug #11182] Refinement with alias causes strange behavior
Issue #11182 has been updated by Koichi Sasada.
Let's discuss with use cases. I don't have good example, but please assume we want to make new Hash class to support something like HashWithIndifferentAccess.
Okay, we need an extra Hash class doing something special.
```ruby
class MyHash < Hash
def initialize *args
args.each{|(k, v)|self[k] = v}
end
alias iterate each
end
h = MyHash.new([:b, 1], [:a, 2])
h.each{|k, v| p [k, v]} # [:b, 1] [:a, 2]
```
Good.
Next time, I invented a nice refinement to iterate Hash contents by ordered.
```ruby
module OrderedHashEach
refine Hash do
def each
sort.each{|k, v|
yield k, v
}
end
end
end
using OrderedHashEach
{b: 1, a: 2}.each{|k, v| p [k, v]} # [:a, 2], [:b, 1]
```
Excellent.
And of course, we can combine MyHash and OrderedHashEach.
```ruby
module OrderedHashEach
refine Hash do
def each
sort.each{|k, v|
yield k, v
}
end
end
end
class MyHash < Hash
def initialize *args
args.each{|(k, v)|self[k] = v}
end
end
h = MyHash.new([:b, 1], [:a, 2])
using OrderedHashEach
h.each{|k, v| p [k, v]} # [:a, 2] [:b, 1]
```
Great.
Wait. `each` is not good terminology for our project. Use `iterate` intead.
```ruby
module OrderedHashEach
refine Hash do
def each
sort.each{|k, v|
yield k, v
}
end
end
end
class MyHash < Hash
def initialize *args
args.each{|(k, v)|self[k] = v}
end
alias iterate each
end
h = MyHash.new([:b, 1], [:a, 2])
using OrderedHashEach
h.iterate{|k, v| p [k, v]} # [:b, 1] [:a, 2]
```
It doesn't affect :( It is unexpected result for me.
Note that I don't want to change this specification. I want to know what is ideal specification.
This time, I made a scenario that we may want to use M::C#foo.
----------------------------------------
Bug #11182: Refinement with alias causes strange behavior
https://bugs.ruby-lang.org/issues/11182#change-52668
* Author: Koichi Sasada
* Status: Feedback
* Priority: Normal
* Assignee: Koichi Sasada
* ruby -v: 2.3dev
* Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN
----------------------------------------
The following script causes strange behavior.
```ruby
class C
def foo
p "C"
end
end
module M
refine C do
def foo
p "Refiend C"
end
end
end
class D < C
alias bar foo
end
using M
D.new.bar
#=> t.rb:21:in `': undefined method `bar' for # (NoMethodError)
```
It seems strange.
Maybe (1) C#foo or (2) M#C#foo should be called. But I'm not sure which is suitable.
Previous versions:
```
ruby 2.0.0p606 (2014-11-28 revision 48636) [i386-mswin32_110]
t.rb:9: warning: Refinements are experimental, and the behavior may change in future versions of Ruby!
"C"
ruby 2.1.5p312 (2015-03-10 revision 49912) [i386-mswin32_110]
"C"
```
---Files--------------------------------
1.PNG (38.7 KB)
2.PNG (43.7 KB)
4.PNG (38.5 KB)
3.PNG (37.9 KB)
alias_affected_by_original_refinement.diff (1.34 KB)
6.PNG (36.6 KB)
7.PNG (40.7 KB)
--
https://bugs.ruby-lang.org/