[ruby-dev:50201] Re: Refinements で定義した to_s を String interpolation が呼んでくれない
From:
Takashi Kokubun <takashikkbn@...>
Date:
2017-08-13 19:05:23 UTC
List:
ruby-dev #50201
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/