1

I'm getting an unexpected return value with this code:

str = ''; 'abc'.chars.map {|c| str<<c}

Expected output:

["a", "ab", "abc"]

Actual output:

["abc", "abc", "abc"]

Adding a puts(str) for debugging:

str = ''; 'abc'.chars.map {|c| puts(str); str<<c}

a
ab
=> ["abc", "abc", "abc"]

Why is the above code not returning the expected output? Thanks.

1
  • You can avoid this confusion by using the # frozen_string_literal: true directive. It will prevent you from using destructive methods like String#<<. There is a performance penalty in some scenarios, but the tradeoff is worth it for most teams. Commented Jan 21, 2022 at 5:23

2 Answers 2

5

From the fine manual:

string << object → string.
Concatenates object to self and returns self

So str << c in the block alters str and then the block itself evaluates to str.

You could say this to get the results you're after:

str = ''
'abc'.chars.map { |c| (str << c).dup }
Sign up to request clarification or add additional context in comments.

2 Comments

Awesome, thanks a lot. Now i know a bit more about ruby blocks. So Object#oid was the same, so the block returned str multiple times. I needed dup to create a different object on each iteration.
@builder-7000 you don't have to use dup necessarily, you could also create new objects by re-assigning str, e.g. 'abc'.chars.map { |c| str = "#{str}#{c}" }
2

It's because each element in your map is returning a reference to str's value, not the actual value of str. So your map is returning 3 references to the value of str and not the value of str at the time of iteration; because each reference to str points to one place in memory at the end that has 'abc', that's why you see the final value of str 3 times.

1 Comment

You might find some of the answers to this question helpful: stackoverflow.com/questions/1872110/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.