I have some Ruby code that uses protected level attr_readers to be able to implement an == method so that we can assert some resultant Calendar is equal to an expected Calendar), but those protected accessors would not be needed for any code besides assertions in test code.
Some code I have looks like this:
class Calendar
def initialize(date_times)
@date_times = date_times
end
def next_date_time
@date_times.find { |time| time - DateTime.now > 0 }
end
def ==(other)
@date_times == other.date_times
end
protected
attr_reader :date_times
end
How can I avoid the need for protected attr_readers? Actually, ideally it would be great if I could remove the need for the def==(......
as well, since it is also only needed for tests!
All the Best, Alex
A First Stab At This:
module Kernel
def subclass_with_equals(class_symbol)
clazz = Kernel.const_get(class_symbol.to_s)
Kernel.subclass_with_default_equals(clazz)
end
private
def self.subclass_with_default_equals(base_class)
sub_class = Class.new(base_class)
sub_class.class_eval do
def ==(other)
instance_variables.all? { |v| self.instance_variable_get(v) == other.instance_variable_get(v) } and other.instance_of? self.class
end
end
sub_class
end
end
And at the top of my spec file I can add this line to add a default == method to my class:
Calendar = sub_class_with_equals :Calendar
This enables me to remove five or six lines from my Calendar class!