From: naruse@... Date: 2014-05-27T03:18:05+00:00 Subject: [ruby-core:62768] [ruby-trunk - Bug #1893] Recursive Enumerable#join is surprising Issue #1893 has been updated by Yui NARUSE. Related to Feature #7226: Added #join method as a shortcut for to_a.join added ---------------------------------------- Bug #1893: Recursive Enumerable#join is surprising https://bugs.ruby-lang.org/issues/1893#change-46886 * Author: Jeremy Kemper * Status: Closed * Priority: Normal * Assignee: Yukihiro Matsumoto * Category: core * Target version: * ruby -v: ruby 1.9.2dev (2009-08-06) [i386-darwin9.7.0] * Backport: ---------------------------------------- =begin >> Bar = Struct.new(:a, :b) => Bar >> bars = [Bar.new('1', '2'), Bar.new('3', '4')] => [#<struct Bar a="1", b="2">, #<struct Bar a="3", b="4">] >> bars * '--' => "1--2--3--4" Surprising? It looks like joining Arrays not Structs. Let's define to_s: >> class Bar; def to_s; 'foo' end end => nil >> bars * '--' => "1--2--3--4" Doesn't work! Strange. But remove to_a and it works! >> class Bar; undef_method :to_a end => Bar >> bars * '--' => "foo--foo" Also note that defining to_str works because ary_join_1 checks rb_check_string_type first, then rb_check_convert_type: >> class Bar; def to_str; 'baz' end end => nil >> bars * '--' => "baz--baz" See r23951 for the change: * array.c (ary_join_1): recursive join for Enumerators (and objects with #to_a). There are two solutions: * remove Struct#to_a, or * tighten the recursive join check for arrays I think we need a to_ary (like to_str) for the recursive array case instead of using to_a. =end -- https://bugs.ruby-lang.org/