I have two instances of a class that I want to swap. Both instances are arrays. I want to swap them using a class method. How do I change/access the instances from within the class method self.collide
?
class MagicBus < Array
attr_writer :seating
def self.collide(bus1, bus2)
stored_arr1 = bus1
stored_arr2 = bus2
bus1 = stored_arr2
bus2 = stored_arr1
return bus1, bus2
end
end
def test_two_magic_buses_collide_and_swap_their_passengers
bus1 = MagicBus.new(["Mark","Dale","Peter"])
bus1_object_id = bus1.object_id
bus2 = MagicBus.new(["James","Patrick","Bardoe"])
bus2_object_id = bus2.object_id
MagicBus.collide(bus1, bus2)
assert_equal ["James","Patrick","Bardoe"], bus1
assert_equal bus1_object_id, bus1.object_id
assert_equal ["Mark","Dale","Peter"], bus2
assert_equal bus2_object_id, bus2.object_id
end
I've tried the code below, doesn't work, but should illustrate what I am trying to do.
def self.collide(bus1, bus2)
stored_arr1 = bus1
stored_arr2 = bus2
bus1 = stored_arr2
bus2 = stored_arr1
self.bus1 = bus2
self.bus2 = bus1
end
Test results are...
....E
Error:
TestMagicBus#test_two_magic_buses_collide_and_swap_their_passengers:
NoMethodError: undefined method `bus1=' for MagicBus:Class
magic_bus.rb:56:in `collide'
magic_bus.rb:126:in `test_two_magic_buses_collide_and_swap_their_passengers'
What you are trying to do isn't possible in Ruby, because Ruby does not have "pass by reference" parameters, but always passes by pointer. This means when you make an assignment in a method to a parameter then this doesn't change the value of the variable on the outside:
a = "Hello"
def make_message(param)
param = "Hello, my Friend"
end
make_message(a)
a => Still has the value "Hello"
Next, in your code example you refer to self.bus1
, but you haven't declared such a member field. This is why you get the error.
To achieve what you are trying to do, you need to use methods of the Array class, which change the provided instances:
a = [1,2,3]
b = [4,5,6]
def swap_array_content(x, y)
temp = y.dup # Need to make a temporary copy here
y.replace(x)
x.replace(temp)
end
swap_array_content(a, b)
p a
p b