Bruce gives the following example in “Seven languages in seven weeks”, Ruby day 3, page 38:
module ActsAsCsv
def self.included(base)
base.extend ClassMethods
end
module ClassMethods
def acts_as_csv
include InstanceMethods
end
end
module InstanceMethods
def read
#fill @csv_contents and @headers from file self.class.to_s.downcase + '.txt'
end
attr_accessor :headers, :csv_contents
def initialize
read
end
end
end
class RubyCsv
include ActsAsCsv
acts_as_csv
end
m = RubyCsv.new
puts m.headers.inspect
puts m.csv_contents.inspect
I do not see any reason for the indirection used by def self.included(base) and ClassMethods. Is there an advantage of the above code over simply including the module InstanceMethods?
In detail: With “simply including the module InstanceMethods” I mean the following code:
module InstanceMethods #defined as above
def read
#fill @csv_contents and @headers from file self.class.to_s.downcase + '.txt'
end
attr_accessor :headers, :csv_contents
def initialize
read
end
end
class RubyCsv
include InstanceMethods
end
m = RubyCsv.new
puts m.headers.inspect
puts m.csv_contents.inspect
Because of duck typing, isn’t this just as good as going via base.extend ClassMethods?
The original code allows you to do this:
While using inheritance is more a matter of taste in this case it would be cleaner if
acts_as_csvwould be added similarly toAActsAsCsvwould be expected to be included by a class from which many classes inherit (like some kind ofBaseModel)Further advantage arise when
acts_as_csvis more elaborate than just includingInstanceMethodsacts_as_csvtakes an argument, for exampleacts_as_csv :separator => " "