How do I avoid multiple chain calls? Imagine code that reads from a file, cleans the data and finally writes the cleaned data to a new file.

Let's briefly define these methods as Ruby stubs:

def write(filename, data)
   File.open(filename, "w") do |f|
      f.write(data.to_yaml)
   end
end

def read(filename)
   YAML.load_file(filename)
end

def clean(data)
   data.map do |line|
      line.strip!
   end
end


We can also have an orchestrator method that triggers the whole logic:

def read_clean_write(filename)
    write(filename, clean(read(filename)))
end


I think that while the isolated read, write and clean methods are modular and apply the single responsibility principle, read_clean_write is quite the opposite (and looks ugly). What is the best way to do that while keeping SRP?
One way would be to wrap it in an object with each method returning self so that methods can be chained.

class DataObject
  def initialize(data)
    @data = data
  end

  def clean
     @data = @data.data.map(&amp;::strip)
     self
  end

  def write(filename)
    File.open(filename, "w") do |f|
      f.write(@data.to_yaml)
    end
    self
  end

end

def read(filename)
  data = YAML.load_file(filename)
  DataObject.new(data)
end


Another way would be to use mixins.

module DataMethods

  def clean
    # need to use the destructive methods to modify self
    map!(&amp;::strip)
    # or each(&amp;:strip!)
    self
  end

  def write(filename)
    File.write(filename, to_yaml)
    self
  end

end

def read(filename)
  YAML.load_file(filename).extend(DataMethods)
end