[#47548] [ruby-trunk - Feature #8696][Open] Process.setproctitle — "znz (Kazuhiro NISHIYAMA)" <redmine@...>

13 messages 2013/07/27

[#47559] [ruby-trunk - Bug #8711][Open] 最近NoMemoryErrorが多い — "naruse (Yui NARUSE)" <naruse@...>

13 messages 2013/07/31

[ruby-dev:47516] Re: Hash#to_hashがHashを返さない

From: "Akinori MUSHA" <knu@...>
Date: 2013-07-17 01:38:58 UTC
List: ruby-dev #47516
At Wed, 17 Jul 2013 08:26:03 +0900,
xibbar wrote:
> 表題はちょっぴりあおり気味ですが、
> RubyのHash#to_hashはHashを返さずにselfを返します。
> Hashのまま使っているんだったらいいのですが、
> これを継承すると、
> % irb
> irb(main):001:0> class MyHash<Hash;end
> => nil
> irb(main):002:0> myhash=MyHash.new
> => {}
> irb(main):003:0> myhash.to_hash
> => {}
> irb(main):004:0> myhash.to_hash.class
> => MyHash
> となってしまいます。
> これ、Array#to_aやString#to_sだと
> ArrayとStringをそれぞれ返します。
>
> Hash#to_hashはHashを返したほうがいいのではないでしょうか?
> 現状、継承したHashからHashを得るためには
> Hash[myhash]とやるのが正解のようで、
> これはこれで裏技に近いと思いました。

Array#to_a に相当するのは Hash#to_h です。こいつは継承してもHashを返し
ますよ。myhash.to_h でOKのはず。

to_str/to_ary/to_hash とフルネームの変換メソッドは、本当にそれぞれ
String/Array/Hash に暗黙の変換もしてほしいというとき「だけ」、それぞれ
のクラスのインスタンスを返すように(再)定義すべしというのが決まりです。
(Rubyでは Klass.try_convert, C APIでは rb_convert_type()等で暗黙に使わ
れるため)

従って、必要なら継承した上で to_hash を再定義すべき(単純なケースなら
alias to_hash to_h)というのが模範解答だと思います。

ただ、 Array#to_a/to_ary はそうなっているけど String#to_s/to_str はそう
ではないようです。おそらく、 String を継承するのは String の拡張した何
かを作りたいケースなので String への自動変換は望まれることが自然だが、
Array/Hash はコンテナであり、拡張というよりは内包するより楽なので継承す
るというケースが多いので自動変換は必ずしも望まれないということなのかな
というのが私の推測です。

--
Akinori MUSHA / http://akinori.org/

In This Thread

Prev Next