Variable swapping in Ruby

Swapping variables is a fundamental concept in programming, often encountered in algorithm development and problem-solving scenarios. While the process is straightforward in many languages, Ruby offers its own particularly elegant and concise syntax for this task. Let’s first explore the more traditional approaches.

First, you might use a temporary variable.

a = 10
b = 12
puts "a: #{a}, b: #{b}"

tmp = a 
a = b
b = tmp

puts "a: #{a}, b: #{b}"

Outputs:

a: 10, b: 12
a: 12, b: 10

A more clever way to do this is with the Bitwise XOR ^ operator.

a = 10
b = 12
puts "a: #{a}, b: #{b}"

a = a ^ b
b = a ^ b
a = a ^ b

puts "a: #{a}, b: #{b}"

outputs:

a: 10, b: 12
a: 12, b: 10

Weird, and looks like magic. Why would calling the same operation 3 times work? The ^ operator is a method on Integer, TrueClass, FalseClass, and NilClass that performs XOR.

The trick here is that XOR does not lose information.

The way I understand it is it basically does something like:

a = 1
b = 2
puts "a: #{a}, b: #{b}"

a = a + b # 1 + 2 = 3, a = 3
b = a - b # 3 - 2 = 1, b = 1
a = a - b # 3 - 1 = 2, a = 2

puts "a: #{a}, b: #{b}"

The Ruby Way

The Ruby way to do this is actually super elegant! Using multiple assignment we can just swap the variables.

a = 1
b = 2
puts "a: #{a}, b: #{b}" # a: 1, b: 2

# Swapping variables using multiple assignment
a, b = b, a
puts "a: #{a}, b: #{b}" # a: 2, b: 1

Strings

What about strings? You cannot subtract a string in Ruby.

"string" ^ "another string"
undefined method `^' for "string":String (NoMethodError)

Could do something like concatenate and substring but that just seems like it’s missing the point. Maybe use a temporary variable for strings.

a = "first"
b = "second"
puts "a: #{a}, b: #{b}" # a: first, b: second

a = a + b # firstsecond
b = a[0..((a.length - b.length)-1)] # first
a = a[b.length..a.length] # second 

puts "a: #{a}, b: #{b}" # a: second, b: first

Ruby being awesome though, really just use multiple assignment :D

Update

Okay I am more clear on how XOR actually works.

> XOR is a binary operation, it stands for “exclusive or”, that is to say the resulting bit evaluates to one if only exactly one of the bits is set.

a = a ^ b means, if a is 0 or b is 0, return 0. If a is 1 OR b is 1, return 1, if a is 1 and b is 1, return 0. Using our example values of a = 10 and b = 12, and we convert to binary: a = 1010, and b = 1100.

The math looks like:

a = a ^ b # 1010 ^ 1100 = 0110 (converted to decimal: 10 ^ 12 = 6)
b = a ^ b # 0110 ^ 1100 = 1010 (6 ^ 12 = 10)
a = a ^ b # 0110 ^ 1010 = 1100 (6 ^ 10 = 12)

Or, a is now 12, and b is now 10.