Confusion with super-Collection of common programming errors
tl;dr: super
behaves in unexpected ways, and variables matter, not just objects.
When super
is called, it’s not called with the object that was passed in.
It’s called with the variable that is called options
at the time of the call. For example, with the following code:
class Parent
def to_xml(options)
puts "#{self.class.inspect} Options: #{options.inspect}"
end
end
class OriginalChild < Parent
def to_xml(options)
options.merge!(:methods => [ :murm_case_name, :murm_type_name ])
super
end
end
class SecondChild < Parent
def to_xml(options)
options = 42
super
end
end
begin
parent_options, original_child_options, second_child_options = [{}, {}, {}]
Parent.new.to_xml(parent_options)
puts "Parent options after method called: #{parent_options.inspect}"
puts
OriginalChild.new.to_xml(original_child_options)
puts "Original child options after method called: #{original_child_options.inspect}"
puts
second_child_options = {}
SecondChild.new.to_xml(second_child_options)
puts "Second child options after method called: #{second_child_options.inspect}"
puts
end
Which produces the output
Parent Options: {}
Parent options after method called: {}
OriginalChild Options: {:methods=>[:murm_case_name, :murm_type_name]}
Original child options after method called: {:methods=>[:murm_case_name, :murm_type_name]}
SecondChild Options: 42
Second child options after method called: {}
You can see that with SecondChild
the super method is called with the variable options
which refers to a Fixnum
of value 42
, not with the object that was originally referred to by options
.
With using options.merge!
, you’d modify the hash object that was passed to you, which means that the object referred to by the variable original_child_options
is now modified, as can be seen in the Original child options after method called: {:methods=>[:murm_case_name, :murm_type_name]}
line.
(Note: I changed options
to 42 in SecondChild, rather than call Hash#merge
, because I wanted to show it wasn’t merely a case of side effects on an object)