Rubyists life made easier with composition operators.
If you write Ruby code and wandered into FP world you might just started writing those little tiny methods inside your classes/modules. And that was awesome to write code like this:
class Import
  # Some code goes here...
  def find_record(row)
    [ Msa.find_or_initialize_by(region_name: row[:region_name], city: row[:city], state: row[:state], metro: row[:metro] ), row ]
  end
  # record is one of:
  # Object - when record was found
  # false - when record was not found
  def update_record(record, attributes)
    record.attributes = attributes
    record
  end
  # record is one of:
  # false
  # ZipRegion
  def validate_record(record)
    case record
    when false
      [:error, nil]
    else
      validate_record!(record)
    end
  end
  # record is ZipRegion object
  def validate_record!(record)
    if record.valid?
      [:ok, record]
    else
      error(record.id, record.errors.messages)
      [:error, record]
    end
  end
  def persist_record!(validation, record)
    case validation
    when :ok
      record.save
    when :error
      false
    end
  end
end
Yeah, I know there is YARD, and argument types are somewhat weird but at the time of coding, I was fascinated with Gregor Kiczales's HTDP courses (that was a ton of fun, sincerely recommend for every adventurous soul).
And next comes dreadful composition:
def process(row, index)
    return if header_row?(row)
    success(row[:region_name], persist_record!(*validate_record(update_record(*find_record(parse_row(row))))))
  end
The pipeline is quite short but already hard to read. Luckily, in Ruby 2.6 we now have 2 composition operators: Proc#>> and its reverse sibling Proc#<<.
And, with a bit of refactoring composition method becomes:
def process(row, index)
    return if header_row?(row)
    composition = method(:parse_row) >>
                             method(:find_record) >>
                             method(:update_record) >>
                             method(:validate_record) >>
                             method(:persist_record!) >>
                             method(:success).curry[row[:region_name]]
    composition.call(row)
Much nicier, don't you think? Ruby just became one step closer to FP-friendly languages family, let's hope there'll be more!
 
 
      
     
      
     
      
    