From: "西塔伸一郎" <omohideporoporo / tvoyama.ne.jp>
Subject: [ruby-list:45473] Re: 文字列から配列への変換について
Date: Fri, 5 Sep 2008 09:38:11 +0900

> あれから、Kernel#Array(arg)を見てみました。
> -------------------------------------
> arg.to_ary と arg.to_a を使い配列に変換、
> いずれのメソッドもない場合は Object#to_a により一要素の配列 [arg] を返す。
> -------------------------------------
> Kernel#Arrayで望む結果は得られるのですが、何故に配列に変換されるのでしょうか?

「 Object#to_a により」の部分は余計ですね。内部で生成されてます。

Ruby 1.9のKernel#Arrayの実体はこんなのです。object.cより。

VALUE
rb_Array(VALUE val)
{
    VALUE tmp = rb_check_array_type(val);  /* to_ary で変換を試みる */

    if (NIL_P(tmp)) {  /* to_ary がないなら */
        /* to_a で変換を試みる */
	tmp = rb_check_convert_type(val, T_ARRAY, "Array", "to_a");
	if (NIL_P(tmp)) { /* to_a もないなら */
	    return rb_ary_new3(1, val); /* 1要素の配列を作成する */
	}
    }
    return tmp;
}


ちなみにRuby 1.8ではeval.cに定義されています。

VALUE
rb_Array(val)
    VALUE val;
{
    VALUE tmp = rb_check_array_type(val);

    if (NIL_P(tmp)) {
	/* hack to avoid invoke Object#to_a */
	VALUE origin;
	ID id = rb_intern("to_a");

	if (search_method(CLASS_OF(val), id, &origin) &&
	    RCLASS(origin)->m_tbl != RCLASS(rb_mKernel)->m_tbl) { /* exclude Kernel#to_a */
	    val = rb_funcall(val, id, 0);
	    if (TYPE(val) != T_ARRAY) {
		rb_raise(rb_eTypeError, "`to_a' did not return Array");
	    }
	    return val;
	}
	else {
	    return rb_ary_new3(1, val);
	}
    }
    return tmp;
}

--
rubikitch
Blog: http://d.hatena.ne.jp/rubikitch/
Site: http://www.rubyist.net/~rubikitch/