I am self-teaching Ruby for one of my classes and cannot wrap my head around a bug that I've encountered. Note: I am not asking anyone to do my project for me; just wondered if anyone could give me insight on this
The gist:
The Set class's deepCopy
method:
def deepCopy(toCopy)
Marshal.load(Marshal.dump(toCopy))
end
The Set class's union
method (this works):
def union(set2)
# clone the current set into union set
unionSet = Set.new
unionSet.deepCopy(self)
# iterate through set 2 and append all unique elements to union set
set2.subscribers.each do |sub|
if !unionSet.subscribers.include?(sub)
unionSet.subscribers.push(sub)
end
end
unionSet.printSet
end
The Set Class's Intersection
method (this does NOT work):
def intersection(set2)
intersectionSet = Set.new
comparisonSet = Set.new
otherSet = Set.new
# choose the smallest set for the comparison set
if @subscribers.size < set2.subscribers.size
comparisonSet.deepCopy(self)
otherSet.deepCopy(set2)
else
comparisonSet.deepCopy(set2)
otherSet.deepCopy(self)
end
#PROBLEM: Both statements below print nothing and both say they are empty when checked.
intersectionSet.printSet
comparisonSet.printSet
# iterate through the comparison set and store all commonalities in intersection set
comparisonSet.subscribers.each do |sub|
puts "Looking for #{sub}"
if otherSet.subscribers.include?(sub)
intersectionSet.subscribers.push(sub)
end
end
intersectionSet.printSet
end
end
This is a pretty basic project, but learning the nuances of Ruby is making it rather difficult. I even tried just cloning self
in the intersection
method like I did in union
, but that didn't work either. This makes me wonder if it some sort of memory issue?
You are not initializing your sets here:
if @subscribers.size < set2.subscribers.size
comparisonSet.deepCopy(self)
otherSet.deepCopy(set2)
else
comparisonSet.deepCopy(set2)
otherSet.deepCopy(self)
end
The returned value isn't assigned to the sets. It should be something like comparisonSet = self.deepCopy(self)
. You can see the method call here has redundant info. I suggest you change your #deepCopy
to
def deep_copy # use snake case as per ruby convention
Marshal.load(Marshal.dump(self))
end
Then you can do something like:
comparison_set = self.deep_copy
other_set = set2.deep_copy
Your current implementation works with union because the union set starts as an empty set and takes in every subscribers you throw at it.
By the way, I'm not sure you need to do the copy here. Seems you can do without it. But of course I haven't seen your whole code.