Sha256: 968a3ec929f80fe517faede406147e8185464b8b87a03e1d9525e972a97c916a

Contents?: true

Size: 1.2 KB

Versions: 3

Compression:

Stored size: 1.2 KB

Contents

#
# Mix-in to make a class Comparable
#
# Use attr_comparabie <attribute list>
# to declare the attributes which should be compared, and the order they should be
# Attributes may be nil; nil attributes sort earlier than non-nil to match SQL NULL ordering
#
module AttrComparable
  include Comparable

  module ClassMethods
    # like <=> but handles nil values
    # returns the code in string form to be eval'd
    def compare_with_nil_code(left, right)
      <<-EOS
        if #{ left }.nil?
          if #{ right }.nil?
            0
          else
            -1
          end
        elsif #{ right }.nil?
          1
        else
          if (cmp_result = (#{ left } <=> #{ right })).nil?
            return nil
          end
          cmp_result
        end
      EOS
    end

    def attr_compare(*attributes)
      attr_exprs = (attributes.flatten).map do |attribute|
        '(' + compare_with_nil_code("self.#{attribute}", "rhs.#{attribute}").strip + ')'
      end

      class_eval <<-EOS
        def <=>(rhs)
          unless rhs.nil?
            #{ attr_exprs.join(".nonzero? || ") }
          end
        end
      EOS
    end
  end

  def self.included(base_class)
    base_class.extend ClassMethods
  end
end

Version data entries

3 entries across 3 versions & 1 rubygems

Version Path
attr_comparable-0.2.0 lib/attr_comparable.rb
attr_comparable-0.2.0.pre.2 lib/attr_comparable.rb
attr_comparable-0.2.0.pre.1 lib/attr_comparable.rb