Is there any advantage of using indirection when you enable the module (from 7 languages ​​in 7 weeks, Ruby 3 day)

Bruce cites 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 see no reason for the indirectness used by def self.included(base) and ClassMethods . Is there an advantage to the above code that just includes the InstanceMethods module?


Detail: "By simply enabling the InstanceMethods module," 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 

Due to duck printing, is this not as good as going through base.extend ClassMethods ?

+4
source share
2 answers

The source code allows you to do this:

 class A include ActsAsCsv end class B < A acts_as_csv end 

While using inheritance is more important, in this case it would be cleaner if

  • more methods than just acts_as_csv will be added in the same way as A is expected
  • ActsAsCsv will be included by a class from which many inherit (for example, some BaseModel )

A further advantage arises when

  • acts_as_csv method acts_as_csv more complex than just InstanceMethods
  • acts_as_csv accepts an argument, for example acts_as_csv :separator => " "
+4
source

One advantage is the communication of the goal, between the code (and the original author) and those who discuss the code later. (And the mechanics of parameter resolution.)

acts_as_csv points to an aspect of RubyCsv behavior.

include ActsAsCsv less declarative. Does it provide additional methods, does it significantly change the functionality of the base class, or both, or ...? You will not know until you read the documents. You may not know until you read the documents for acts_as_csv , but this is more communicative.

This is the difference between "this is what I am" and "this is what I can." Don't get into a concrete example: consider the mechanics of what is being done and how.

This mechanism is one of the reasons why Ruby code may look like a problem that it is trying to solve, and not just Ruby. This is one way of implementing micro-DSL that helps make Ruby more expressive than it.

+3
source

Source: https://habr.com/ru/post/1385738/


All Articles