Skip to content

Latest commit

 

History

6 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Pipey

Build functional pipelines in Ruby by taking advantage of Ruby's keyword arguments for "pattern matching."

Installation

Add this line to your application's Gemfile:

gem 'pipey'

And then execute:

$ bundle

Or install it yourself as:

$ gem install pipey

Usage

Pipey::Line

Pipey::Line can be used to work with any object in a pipe-line manner.

class MyPipe < Pipey::Line
  extend Pipey::Steps::Scanner[/^run_/]

  def run_foo(num, multiply:, **)
    num * multiply
  end

  def run_bar(num, add:, **)
    num + add
  end
end

MyPipe.call(1, multiply: 10, add: 5) #=> 15

Pipey::Chain

Pipey::Chain is a slightly fancier way to work with chainable objects like Array or ActiveRecord::Relation. In the example below, map and select are automatically delegated to the array.

class MyPipe < Pipey::Chain
  extend Pipey::Steps::Scanner[/^run_/]

  def run_foo(multiply:, **)
    map { |v| v * a }
  end

  def run_bar(minimum:, **)
    select { |v| v > minimum }
  end
end

MyPipe.call([1, 2, 3], multiply: 5, minimum: 6) #=> [10, 15]

Pipey::Steps::Scanner

Pipey::Steps::Scanner takes a Regexp as an argument, and it will run the methods that match the regexp.

class MyPipe < Pipey::Line
  extend Pipey::Steps::Scanner[/^run_/]
  
  def run_something(**); end # this will be called
  def something(**); end     # this will not be called
end

Pipey::Steps::DSL

If you don't like the automatic behavior provided by Pipey::Steps::Scanner, you can use Pipey::Steps::DSL instead. With it, you can list out your steps.

class MyPipe < Pipey::Line
  extend Pipey::Steps::DSL

  step :foo
  step :bar

  def foo(num, multiply:, **)
    num * multiply
  end

  def bar(num, add:, **)
    num + add
  end
end

MyPipe.call(1, multiply: 10, add: 5) #=> 15

Pipey::Extensions::RequiredKeys

This extension won't call a step if it requires a key that is falsy.

class MyPipe < Pipey::Line
  extend Pipey::Steps::Scanner[/^run_/]
  extend Pipey::Extensions::RequiredKeys

  def run_foo(num, multiply:, **)
    num * multiply
  end

  def run_bar(num, add:, **)
    num + add
  end
end

MyPipe.call(1, multiply: 10, add: 5) #=> 15
MyPipe.call(1, multiply: 10)         #=> 10
MyPipe.call(1, add: 5)               #=> 6

Pipey::Extensions::IgnoreNil

By using this extension, any step that returns nil will be ignored.

class MyPipe < Pipey::Line
  extend Pipey::Steps::Scanner[/^run_/]
  extend Pipey::Extensions::IgnoreNil

  def run_foo(num, add:, **)
    num + add if add > 5
  end
end

MyPipe.call(1, add: 5) #=> 1
MyPipe.call(1, add: 6) #=> 6

Pipey::Extensions::Ignore

This can be used to create more complicated ignores.

For example, the implementation of IgnoreNil looks like this:

Pipey::Extensions::Ignore.new(&:nil?)

If you wanted to ignore any value equal to 5, you could do this:

class MyPipe < Pipey::Line
  extend Pipey::Extensions::Ignore.new { |v| v == 5 }
end

TODO

  • Pipey::Steps::Scanner does not guarantee order.

Contributing

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

About

Functional pipelines for Ruby

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages