Skip to content

Latest commit

 

History

33 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

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

Stars

43 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages