The other answerers are all correct, but a friend asked me to explain this to him and what it really boils down to is how Ruby handles variables, so I thought I would share some simple pictures / explanations I wrote for him (apologies for the length and probably some oversimplification):
Q1: What happens when you assign a new variable str to a value of 'foo'?
str="foo"
str.object_id # => 2000

A: A label called str is created that points at the object 'foo', which for the state of this Ruby interpreter happens to be at memory location 2000.
Q2: What happens when you assign the existing variable str to a new object using =?
str="bar".tap{|b| puts "bar: #{b.object_id}"} # bar: 2002
str.object_id # => 2002

A: The label str now points to a different object.
Q3: What happens when you assign a new variable = to str?
str2 = str
str2.object_id # => 2002

A: A new label called str2 is created that points at the same object as str.
Q4: What happens if the object referenced by str and str2 gets changed?
str2.replace 'baz'
str2 # => 'baz'
str # => 'baz'
str.object_id # => 2002
str2.object_id # => 2002

A: Both labels still point at the same object, but that object itself has mutated (its contents have changed to be something else).
How does this relate to the original question?
It’s basically the same as what happens in Q3/Q4; the method gets its own private copy of the variable / label (str2) that gets passed in to it (str). It can’t change which object the label str points to, but it can change the contents of the object that they both reference to contain else:
str="foo"
def mutate(str2)
puts "str2: #{str2.object_id}"
str2.replace 'bar'
str2 = 'baz'
puts "str2: #{str2.object_id}"
end
str.object_id # => 2004
mutate(str) # str2: 2004, str2: 2006
str # => "bar"
str.object_id # => 2004