Skip to content

sbscully/functo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

33 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Functo

Composable method objects in ruby.

Usage

class AddsOne
  include Functo.call :add, :number

  def add
    number + 1
  end
end

AddsOne[1] # `.call` or `.()` also work
# => 2

class Multiplies
  include Functo.call :multiply, :foo, :bar

  def multiply
    foo * bar
  end
end

Multiplies[2, 3]
# => 6

Functo objects can be used in place of a Proc.

[1, 2, 3].map(&AddsOne)
# => [2, 3, 4]

Use slurp to splat array inputs.

[[1, 2], [3, 4], [5, 6]].map(&Multiplies.slurp)
# => [2, 12, 30]

Composition

MultipliesAddsOne = Multiplies >> AddsOne

MultipliesAddsOne[2, 3]
# => 7

>> splats intermediate results. Use > to compose without splatting intermediate results.

class SplitsDigits
  include Functo.call :split, :number

  def split
    number.to_s.split(//).map(&:to_i)
  end
end

class Sums
  include Functo.call :sum, :arr

  def sum
    arr.reduce(:+)
  end
end

SumsDigits = SplitsDigits >> Sums
SumsDigits[1066]
# => ArgumentError: wrong number of arguments (4 for 1)

SumsDigits2 = SplitsDigits > Sums
SumsDigits2[1066]
# => 13

Any object that responds to to_proc can be made composable.

SquareRoots = Functo.wrap ->(n) { Math.sqrt(n) }

SquareRootsAddsOne = SquareRoots >> AddsOne
SquareRootsAddsOne[16]
# => 5.0

AddsOneStringifies = AddsOne >> Functo.wrap(&:to_s)
AddsOneStringifies[3]
# => "4"

Filters

class DividesTwo
  include Functo.call :divide, number: ->(n) { Float(n) }

  def divide
    2 / number
  end
end

DividesTwo['4']
# => 0.5

class DividesThree
  include Functo.call :divide, number: :to_f

  def divide
    3 / number
  end
end

DividesThree['4']
# => 0.75

A filter can be any object that responds to to_proc, call, or [].

For example using dry-types.

require 'dry-types'

module Types
  include Dry::Types.module
end

class Squares
  include Functo.call :square, number: Types::Strict::Int

  def square
    number**2
  end
end

Squares[4]
# => 16

Squares['4']
# => Dry::Types::ConstraintError: "4" violates constraints

Acknowledgements

Functo was inspired by:

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/sbscully/functo.

License

The gem is available as open source under the terms of the MIT License.

About

Composable method objects in ruby.

Resources

License

Stars

Watchers

Forks

Packages

No packages published