Control flow exercises my_join

Somehow every time I try to solve this. It modifies ‘arr’. Turns it into a string. Which, the way the RSPEC is set up, means that for the next test, arr is now a modified string. I’ve tried to solve it with #inject, #each, and now I’m doing it with a while loop. Each time, the first test passes, but from then on I’m just adding to the result of the first test.

Can someone explain to me how this permanently modifies arr? Those two puts statements at the end output the same exact thing. arr == str # => true

def my_join(arr, separator = “”)
str = arr[0] || ""
i = 1
while i < arr.length
str << separator << arr[i]
i += 1
end
puts arr
puts str
str
end

(Mine’s indented, I don’t know why it’s displaying like that.)

I got it to pass by going into the RSPEC and reassigning arr = [“a”, “b”, “c”] at the beginning of all three ‘it’ statements. But I still want to know why that’s happening.

I think it’s because you set the variable str to arr[0] on line 2. That means you’re modifying the first element of the arr argument.

Hope that helps!

1 Like

wait…so assignment works in both directions in Ruby? I can’t ever assign an element in an array to a variable without modifying the array?

I assume I’m doing something wrong and maybe it does have something to do with that line. But I don’t think it has to do with the assignment. Maybe putting it in an | | statement, not that that makes sense to me either…

If I go into pry, the assignment operator doesn’t work like that.
> arr = [“z”]
=> [“z”]
> str = arr[0]
=> “z”
> str
=> “z”
> arr
=> [“z”]

You’re using shovel operators on line 5, so you’re appending separator and arr[i] to str in your solution. You alter str by using the shovel operator.

As an example, let’s say separator = "/" and arr = ["a", "b"].

[1] pry(main)> separator = "!"
=> "!"
[2] pry(main)> arr = ["a", "b"]
=> ["a", "b"]
[3] pry(main)> str = arr[0]
=> "a"
[4] pry(main)> str
=> "a"
[5] pry(main)> str << separator
=> "a!"
[6] pry(main)> str
=> "a!"
[7] pry(main)> arr
=> ["a!", "b"]

So the value of arr becomes ["a!", "b"].

1 Like

Right on! touché and thank you.

Very odd functionality to me, but good to know!

1 Like

Whoah, this weirded me out to read. I opened up IRB and played around with it. You can use
string + separator
or string += separator

and you will not modify the array from which you made the assignment

but
str.concat(separator) works like << and will modify the object referenced by the variable

I guess when you use << on a variable it looks for what that variable points to and then performs the operation, which is why it gets linked through assignment. Anyone else understand this better? I also thought assignment was unidirectional.

The first answer clarified it for me: http://stackoverflow.com/questions/4684446/why-is-the-shovel-operator-preferred-over-plus-equals-when-building-a

1 Like