Module: Enumerable

Defined in:
lib/sortsmith/core_ext/enumerable.rb

Overview

Extensions to Ruby's built-in Enumerable module.

Sortsmith extends Enumerable to provide enhanced sorting capabilities while preserving the original behavior when used with blocks.

The key enhancement is allowing sort_by to be called without a block, which returns a Sortsmith::Sorter instance for method chaining.

Examples:

Original behavior (unchanged)

[1, 2, 3].sort_by { |n| -n }
# => [3, 2, 1]

New chainable behavior

users.sort_by.dig(:name).downcase.sort
# => Returns Sorter instance for chaining

See Also:

Instance Method Summary collapse

Instance Method Details

#og_sort_byObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Stores the original sort_by method before extension.

This alias preserves Ruby's original sort_by behavior, allowing Sortsmith to enhance the method while maintaining full backward compatibility when blocks are provided.



33
# File 'lib/sortsmith/core_ext/enumerable.rb', line 33

alias_method :og_sort_by, :sort_by

#sort_by(field = nil, *positional, **keyword, &block) ⇒ Array, Sortsmith::Sorter

Note:

This method maintains full backward compatibility with Ruby's original sort_by

Note:

When field is nil, returns a plain Sorter instance for manual chaining

Enhanced sort_by that supports both traditional block usage and direct field extraction.

This method extends Ruby's built-in sort_by to provide a fluent, chainable API for sorting operations. When called with a block, it behaves exactly like the original sort_by. When called without a block, it returns a Sortsmith::Sorter instance for method chaining.

The direct syntax (sort_by(field)) provides a concise way to sort by a specific field or method without verbose chaining, making simple sorting operations more readable and intuitive.

Examples:

Traditional block usage (unchanged)

users.sort_by { |user| user.name.downcase }
# => sorted array

Direct field syntax (new)

users.sort_by(:name).insensitive.sort
# => sorted array via method chaining

Direct syntax with immediate result

users.sort_by(:score).desc.first(3)
# => top 3 users by score

Chainable interface without field

users.sort_by.dig(:profile, :email).sort
# => sorted by nested email field

Mixed key types

mixed_data = [
  { name: "Bob" },        # symbol key
  { "name" => "Alice" }   # string key
]
mixed_data.sort_by(:name, indifferent: true).sort
# => handles both key types gracefully

Object method sorting

products.sort_by(:calculate_price).desc.sort
# => sorted by calculated price method

Dynamic field selection

sort_field = params[:sort_by]  # might be nil
users.sort_by(sort_field).sort
# => gracefully handles nil field

Integration with enumerable methods

users.sort_by(:created_at).desc.take(10)
# => newest 10 users without breaking the chain

Parameters:

  • field (Symbol, String, nil) (defaults to: nil)

    Optional field name for direct extraction

  • positional (Array)

    Additional positional arguments for extraction

  • keyword (Hash)

    Additional keyword arguments for extraction

  • block (Proc, nil)

    Optional block for traditional sort_by behavior

Returns:

Raises:

  • (ArgumentError)

    When extraction results in incomparable types

See Also:

Since:

  • 1.0.0



101
102
103
104
105
106
107
108
# File 'lib/sortsmith/core_ext/enumerable.rb', line 101

def sort_by(field = nil, *positional, **keyword, &block)
  return og_sort_by(&block) if block

  sorter = Sortsmith::Sorter.new(self)
  return sorter if field.nil?

  sorter.extract(field, *positional, **keyword)
end