James Gray
8/27/2006 4:14:00 PM
On Aug 26, 2006, at 10:05 PM, ako... wrote:
> it looks like map+join use fewer objects than inject. even though map
> creates a whole new array. i would expect inject to use fewer objects.
> strange...
It has to do with the block you gave inject() and the definition of
String.+(). Watch:
>> ("a".."j").inject(String.new) do |res, let|
?> new_str = res + let
>> puts "#{new_str.object_id}: #{new_str.inspect}"
>> new_str
>> end
1669064: "a"
1668834: "ab"
1668624: "abc"
1668424: "abcd"
1668304: "abcde"
1668144: "abcdef"
1668064: "abcdefg"
1667854: "abcdefgh"
1667764: "abcdefghi"
1667534: "abcdefghij"
=> "abcdefghij"
Each of those intermediate Strings is a new object, which is right.
That's what String.+() does:
$ ri -T String#+
--------------------------------------------------------------- String#+
str + other_str => new_str
------------------------------------------------------------------------
Concatenation---Returns a new String containing other_str
concatenated to str.
"Hello from " + self.to_s #=> "Hello from main"
The keywords there being "new String." String does have an append
method though:
$ ri -T 'String#<<'
-------------------------------------------------------------- String#<<
str << fixnum => str
str.concat(fixnum) => str
str << obj => str
str.concat(obj) => str
------------------------------------------------------------------------
Append---Concatenates the given object to str. If the object is a
Fixnum between 0 and 255, it is converted to a character before
concatenation.
a = "hello "
a << "world" #=> "hello world"
a.concat(33) #=> "hello world!"
And if we use that, we can get down to less objects than map(),
because we don't need the Array:
>> ("a".."j").inject(String.new) do |res, let|
?> same_str = res << let
>> puts "#{same_str.object_id}: #{same_str.inspect}"
>> same_str
>> end
938158: "a"
938158: "ab"
938158: "abc"
938158: "abcd"
938158: "abcde"
938158: "abcdef"
938158: "abcdefg"
938158: "abcdefgh"
938158: "abcdefghi"
938158: "abcdefghij"
=> "abcdefghij"
Hope that helps.
James Edward Gray II