There comes a moment of pondering, is Ruby a pass by value or pass by reference language? Or in other words, which strategy of passing arguments to methods does it employ. This concerns both junior Ruby developers and the senior staff directors of chief technical officers.
To get a full answer and understanding one can go through this series of articles:
- Variable references and mutability of Ruby objects
- Ruby objects mutating and non-mutating methods
- Object passing in Ruby – pass by reference or pass by value
But. If one just want to refresh that. Quickly. Then.

Method for numerics (immutable objects):
def plus_int(m)
puts "initial object id: #{m.object_id}"
m = m + 1
puts "modified object id: #{m.object_id}"
m
end
The effect:
> n = 5
> n.object_id
=> 11
> plus(n)
initial object id: 11
modified object id: 13
=> 6
> n
=> 5
For strings (mutable objects):
def plus_str(m)
puts "initial object id: #{m.object_id}"
m = m.upcase
puts "modified object id: #{m.object_id}"
m
end
def plus_str!(m)
puts "initial object id: #{m.object_id}"
m.upcase!
puts "modified object id: #{m.object_id}"
m
end
For mutable objects like Strings:
> s = "hello"
> s.object_id
=> 574700
> plus_str(s)
initial object id: 574700
modified object id: 582660
=> "HELLO"
> s
=> "hello"
> plus_str!(s)
initial object id: 574700
modified object id: 574700
=> "HELLO"
> s
=> "HELLO"
So:
- Ruby is not pass by value because we wouldn’t be able to mutate the state of an object referenced by the variable
s
in theplus_str!
method - Ruby is not pass by reference because we wouldn’t be able to reassign the variable
m
in bothplus_int
andplus_str
methods without affecting it outside of the method - Ruby is pass by value of reference because:
- we are able to affect the value of the object referenced by the passed argument
- we are unable to affect the relationship of a variable and it’s reference outside of the method through the passed argument
Please criticise if you find something wrong in my simplification of the above!