* [ruby-dev:49007] [Ruby trunk - Bug #11189] [Open] alias prepended module
[not found] <redmine.issue-11189.20150527195807@ruby-lang.org>
@ 2015-05-27 19:58 ` ko1
2015-05-27 20:04 ` [ruby-dev:49005] [Ruby trunk - Bug #11189] " ko1
2019-08-12 22:59 ` [ruby-dev:50834] [Ruby master Bug#11189] " merch-redmine
2 siblings, 0 replies; 3+ messages in thread
From: ko1 @ 2015-05-27 19:58 UTC (permalink / raw)
To: ruby-dev
Issue #11189 has been reported by Koichi Sasada.
----------------------------------------
Bug #11189: alias prepended module
https://bugs.ruby-lang.org/issues/11189
* Author: Koichi Sasada
* Status: Open
* Priority: Normal
* Assignee: Yukihiro Matsumoto
* ruby -v:
* Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN
----------------------------------------
```ruby
module P
def m1
p :P_m1
super
end
def m2
p :P_m2
super
end
end
class C0
def m1
p :C0_m1
end
end
class C1 < C0
def m1
p :C1_m1
super
end
prepend P
alias m2 m1
end
C1.new.m2
```
このプログラムは、
```
:P_m2
:P_m1
:C0_m1
```
という結果になります。super で辿っているはずなのに、同じモジュールのメソッドが 2 回呼ばれます。super で辿っていったら、必ず継承元へ行く、2度同じクラスは来ない、という常識があると思っていたので、Ruby 的にはかなり驚きました。
この挙動は、設定時に:
* alias で C1 のメソッドテーブルに、C1#m2 を P#m1 へ飛ばすように設定する
次に、呼び出された時に:
* m2 が呼ばれる
* P#m2 を実行する
* P#m2 の super を呼ぶ
* C1#m2 を見ると、P#m1 へ飛ぶように alias が設定されている
* P#m1 を実行する、super する
* (なんでか C1#m1 をスキップする なんで?)
* C0#m1 が呼ばれる
となっておりました。P#m2 -> P#m1 という流れがとても気持ち悪いですが、これは意図された挙動でしょうか。
C1#foo が呼ばれないのも気持ち悪いですが。
ちなみに、2.1 では C1#m1 が呼ばれていました。
```
* ruby 2.1.5p312 (2015-03-10 revision 49912) [i386-mswin32_110]
:P_m2
:P_m1
:C1_m1
:C0_m1
```
たしか、alias + prepend の議論が以前あったと思うのですが。
あ、[Bug #7842] だ。
ちなみに、私の予想は
```
:P_m1
:C1_m1
:C0_m1
```
かなぁ。
--
https://bugs.ruby-lang.org/
^ permalink raw reply [flat|nested] 3+ messages in thread
* [ruby-dev:49005] [Ruby trunk - Bug #11189] alias prepended module
[not found] <redmine.issue-11189.20150527195807@ruby-lang.org>
2015-05-27 19:58 ` [ruby-dev:49007] [Ruby trunk - Bug #11189] [Open] alias prepended module ko1
@ 2015-05-27 20:04 ` ko1
2019-08-12 22:59 ` [ruby-dev:50834] [Ruby master Bug#11189] " merch-redmine
2 siblings, 0 replies; 3+ messages in thread
From: ko1 @ 2015-05-27 20:04 UTC (permalink / raw)
To: ruby-dev
Issue #11189 has been updated by Koichi Sasada.
今、こんなコードだと、
* C1 (m_tbl 空)
* T_ICLASS(m_tbl 空) -> P
* T_ICLASS(C1 の m_tbl) -> C1
* C0
* Object...
という継承関係(下が親)が作られるけど、alias のために C1 に m_tbl 作らないといかんね、って話な気がします。が、なんか以前この話をしていたことがあったような。結局 C1 にはテーブル作れないんでしたっけ。
メソッド定義については、
* alias の時は、C1::m_tbl へ
* メソッド定義の時は T_ICLASS(C1 の m_tbl)へ
と分けなきゃいけないのも、なんかかっこ悪いですね。
----------------------------------------
Bug #11189: alias prepended module
https://bugs.ruby-lang.org/issues/11189#change-52657
* Author: Koichi Sasada
* Status: Open
* Priority: Normal
* Assignee: Yukihiro Matsumoto
* ruby -v:
* Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN
----------------------------------------
```ruby
module P
def m1
p :P_m1
super
end
def m2
p :P_m2
super
end
end
class C0
def m1
p :C0_m1
end
end
class C1 < C0
def m1
p :C1_m1
super
end
prepend P
alias m2 m1
end
C1.new.m2
```
このプログラムは、
```
:P_m2
:P_m1
:C0_m1
```
という結果になります。super で辿っているはずなのに、同じモジュールのメソッドが 2 回呼ばれます。super で辿っていったら、必ず継承元へ行く、2度同じクラスは来ない、という常識があると思っていたので、Ruby 的にはかなり驚きました。
この挙動は、設定時に:
* alias で C1 のメソッドテーブルに、C1#m2 を P#m1 へ飛ばすように設定する
次に、呼び出された時に:
* m2 が呼ばれる
* P#m2 を実行する
* P#m2 の super を呼ぶ
* C1#m2 を見ると、P#m1 へ飛ぶように alias が設定されている
* P#m1 を実行する、super する
* (なんでか C1#m1 をスキップする なんで?)
* C0#m1 が呼ばれる
となっておりました。P#m2 -> P#m1 という流れがとても気持ち悪いですが、これは意図された挙動でしょうか。
C1#foo が呼ばれないのも気持ち悪いですが。
ちなみに、2.1 では C1#m1 が呼ばれていました。
```
* ruby 2.1.5p312 (2015-03-10 revision 49912) [i386-mswin32_110]
:P_m2
:P_m1
:C1_m1
:C0_m1
```
たしか、alias + prepend の議論が以前あったと思うのですが。
あ、[Bug #7842] だ。
ちなみに、私の予想は
```
:P_m1
:C1_m1
:C0_m1
```
かなぁ。
--
https://bugs.ruby-lang.org/
^ permalink raw reply [flat|nested] 3+ messages in thread
* [ruby-dev:50834] [Ruby master Bug#11189] alias prepended module
[not found] <redmine.issue-11189.20150527195807@ruby-lang.org>
2015-05-27 19:58 ` [ruby-dev:49007] [Ruby trunk - Bug #11189] [Open] alias prepended module ko1
2015-05-27 20:04 ` [ruby-dev:49005] [Ruby trunk - Bug #11189] " ko1
@ 2019-08-12 22:59 ` merch-redmine
2 siblings, 0 replies; 3+ messages in thread
From: merch-redmine @ 2019-08-12 22:59 UTC (permalink / raw)
To: ruby-dev
Issue #11189 has been updated by jeremyevans0 (Jeremy Evans).
ko1 (Koichi Sasada) wrote:
> ちなみに、私の予想は
>
> ```
> :P_m1
> :C1_m1
> :C0_m1
> ```
>
> かなぁ。
This output would be against my expection. If `C1` prepends `P`, then methods in `P` must be considered before methods in `C1`. Consider `C1.ancestors`:
```ruby
[P, C1, C0, Object, Kernel, BasicObject]
```
`P#m2` must be called before `C1#m2`, and `alias m2 m1` in `C1` only modifies the method table in `C1`, not in `P`.
All Ruby versions I tested have the same behavior as Ruby 2.1:
```ruby
:P_m2
:P_m1
:C1_m1
:C0_m1
```
There does appear to be a related bug in `super_method`, though:
```ruby
C1.new.method(:m2)
# => #<Method: C1(P)#m2>
C1.new.method(:m2).super_method
# => #<Method: C1(P)#m2(m1)>
C1.new.method(:m2).super_method.super_method
# => nil
# Should be #<Method: C1#m1>
```
Note that because of the way `alias` works with `prepend`, you can get an infinite loop in method lookup with aliases and only calling `super`:
```ruby
module P
def m1
super
end
def m2
super
end
end
class C
prepend P
alias m2 m1
alias m1 m2
end
C.new.m2
# SystemStackError
```
----------------------------------------
Bug #11189: alias prepended module
https://bugs.ruby-lang.org/issues/11189#change-80665
* Author: ko1 (Koichi Sasada)
* Status: Open
* Priority: Normal
* Assignee: matz (Yukihiro Matsumoto)
* Target version:
* ruby -v:
* Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN
----------------------------------------
```ruby
module P
def m1
p :P_m1
super
end
def m2
p :P_m2
super
end
end
class C0
def m1
p :C0_m1
end
end
class C1 < C0
def m1
p :C1_m1
super
end
prepend P
alias m2 m1
end
C1.new.m2
```
このプログラムは、
```
:P_m2
:P_m1
:C0_m1
```
という結果になります。super で辿っているはずなのに、同じモジュールのメソッドが 2 回呼ばれます。super で辿っていったら、必ず継承元へ行く、2度同じクラスは来ない、という常識があると思っていたので、Ruby 的にはかなり驚きました。
この挙動は、設定時に:
* alias で C1 のメソッドテーブルに、C1#m2 を P#m1 へ飛ばすように設定する
次に、呼び出された時に:
* m2 が呼ばれる
* P#m2 を実行する
* P#m2 の super を呼ぶ
* C1#m2 を見ると、P#m1 へ飛ぶように alias が設定されている
* P#m1 を実行する、super する
* (なんでか C1#m1 をスキップする なんで?)
* C0#m1 が呼ばれる
となっておりました。P#m2 -> P#m1 という流れがとても気持ち悪いですが、これは意図された挙動でしょうか。
C1#foo が呼ばれないのも気持ち悪いですが。
ちなみに、2.1 では C1#m1 が呼ばれていました。
```
* ruby 2.1.5p312 (2015-03-10 revision 49912) [i386-mswin32_110]
:P_m2
:P_m1
:C1_m1
:C0_m1
```
たしか、alias + prepend の議論が以前あったと思うのですが。
あ、[Bug #7842] だ。
ちなみに、私の予想は
```
:P_m1
:C1_m1
:C0_m1
```
かなぁ。
--
https://bugs.ruby-lang.org/
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2019-08-12 22:59 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <redmine.issue-11189.20150527195807@ruby-lang.org>
2015-05-27 19:58 ` [ruby-dev:49007] [Ruby trunk - Bug #11189] [Open] alias prepended module ko1
2015-05-27 20:04 ` [ruby-dev:49005] [Ruby trunk - Bug #11189] " ko1
2019-08-12 22:59 ` [ruby-dev:50834] [Ruby master Bug#11189] " merch-redmine
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).