[ruby-dev:50202] Re: Refinements で定義した to_s を String interpolation が呼んでくれない
From:
Tsukuru Tanimichi <ttanimichi@...>
Date:
2017-08-14 01:00:58 UTC
List:
ruby-dev #50202
例が分かりにくかったかもしれません。
String#to_s の再定義ではなく、A#to_sを定義しています。
2017/08/14 4:05、Takashi Kokubun <takashikkbn@gmail.com> のメッセージ:
> k0kubunです
>
> 経緯や意図については私は認識していませんが、
> 渡されたオブジェクトの型がStringの場合はそれをそのまま使うという挙動のため、
> Refinementsに限った話ではなく、グローバルにString#to_sを再定義しても呼ばれないと思います。
>
> 個人的には String#to_s を上書きしたいことがないので
> 後方互換性的にもそのままの挙動で構わないのですが、
> 私もこの挙動を見たときは一貫性がないように感じたので
> これが意図的なのかどうかは経緯に詳しい方にお聞きしたいです。
>
> 2017年8月9日 23:43 Tsukuru Tanimichi <ttanimichi@ttanimichi.com>:
>> はじめまして。谷道と申します。
>>
>> 既出だったらすみません。bugs.ruby-lang.org でも検索したんですが
>> それっぽいチケットが見当たらなかったので確認させてください。
>>
>> Refinements で定義した to_s を String interpolation が呼んでくれないのですが、これって仕様なんですかね?
>> String literal の評価が using B しているスコープの外で行われる、ということでしょうか。
>>
>> ```
>> $ ruby -v
>> ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-darwin16]
>> ```
>>
>> ```ruby
>> class A
>> end
>>
>> module B
>> refine A do
>> def to_s
>> 'b'
>> end
>> end
>> end
>>
>> class C
>> using B
>>
>> def initialize
>> @a = A.new
>> end
>>
>> def c1
>> @a.to_s
>> end
>>
>> def c2
>> "#{@a}"
>> end
>>
>> def c3
>> puts "#{@a}"
>> end
>> end
>>
>> puts C.new.c1 #=> b
>> puts C.new.c2 #=> #<A:0x007fb05ba3e928>
>> C.new.c3 #=> #<A:0x007fb05ba3e7e8>
>> ```
>>
>> c1, c2, c3 ともに "b" となることを想像していました。
>>
>> --
>> 谷道 創(Tsukuru Tanimichi)
>> https://ttanimichi.com/