bsflow
A couple of classes that represent useful control flow patterns (conditional loops, pipelines etc).
When to use it?
In pseudo-funtional programming.
Installation
Add this line to your application's Gemfile:
gem 'bsflow'
And then execute:
$ bundle
Or install it yourself as:
$ gem install bsflow
Usage
Reqiure proper class.
require "bsflow/pipeline"
Use it.
square_number_generator = BSFlow:Pipeline.new(procs: [random_int, square])
All classes have just one public method: #call.
Some classes have dependencies (injected in constructor) called "procs". They are objects that respond to #call method.
API
Class BSFlow::Pipeline
It passes a value through every proc and returns a final value. Output of the previous proc is input of the next proc.
Source code:
module BSFlow
class Pipeline
def initialize(*args, procs: [])
@procs = args + procs
end
def call(*args)
output = @procs[0].call(*args)
if @procs.length == 1
return output
else
@procs[1..-1].each do |proc|
output = proc.call(output)
end
output
end
end
end
end
Require
require "bsflow/pipeline"
Constructor
BSFlow:Pipeline.new(procs: procs) # => new_pipeline
# or
BSFlow:Pipeline.new(*procs) # => new_pipeline
# or
BSFlow:Pipeline.new(*first_part_of_procs, procs: rest_of_procs) # => new_pipeline
Paramaters:
- procs - an array of procs or objects responding on
.call
message. The first proc takes the "main" input of the class (any number of arguments). The result is passed to the next proc as input. The output of the last proc is the output of.call
method of Pipeline class. The procs can be passed as a normal arguments or as a list arguments
Class BSFlow::StdoutAdapter
It allows to "connect" standard output stream to an object that expects #call
mathod.
Source code:
module BSFlow
class StdoutAdapter
def initialize(stdout:)
@stdout = stdout
end
def call(string)
@stdout.puts(string)
end
end
end
Require
require "bsflow/stdout_adapter"
Constructor
BSFlow:StdoutAdapter.new(procs: procs) # => new_adapter
Paramaters:
- stdout - an object that respond to
.#puts
message with one argument.
Class BSFlow::StdinAdapter
It allows to "connect" standard input stream to an object that expects #call
mathod.
Source code:
module BSFlow
class StdinAdapter
def initialize(stdin:)
@stdin = stdin
end
def call()
@stdin.gets.chomp
end
end
end
Require
require "bsflow/stdin_adapter"
Constructor
BSFlow:StdinAdapter.new(stdin: stdin) # => new_adapter
Paramaters:
- stdin - an object that respond to
.#gets
message. The chomped output of this object is the output of.call
method of StdinAdapter class.
Class BSFlow::SquareBracketsAdapter
It passes a value to [] method of a hash or any objects that response to [] method.
Source code:
module BSFlow
class SquareBracketsAdapter
def initialize(map:)
@map = map
end
def call(symbol)
@map[symbol]
end
end
end
Require
require "bsflow/square_brackets_adapter"
Constructor
BSFlow:SquareBracketsAdapter.new(map: map) # => new_square_brackets_adapter
Paramaters:
- map - an object that respond to
.#[]
message. It takes the "main" input of the class (one argument). The output of this object is the output of.call
method of SquareBracketsAdapter class.
Class BSFlow::FirstArg
It just returns first pased argument and ignores the rest. Used to reduce number of arguments.
Source code:
module BSFlow
class FirstArg
def call(*args)
args.first
end
end
end
Require
require "bsflow/first_arg"
Constructor
BSFlow:FirstArg.new # => new_first_arg
Class BSFlow::LastArg
It just returns last pased argument and ignores the rest. Used to reduce number of arguments.
Source code:
module BSFlow
class LastArg
def call(*args)
args.last
end
end
end
Require
require "bsflow/last_arg"
Constructor
BSFlow:LastArg.new # => new_last_arg
Class BSFlow::Self
It returns unmodified argument.
Source code:
module BSFlow
class Self
def call(input)
input
end
end
end
Require
require "bsflow/self"
Constructor
BSFlow:Self.new # => new_self
Class BSFlow::True
It returns true no matter what input it takes.
Source code:
module BSFlow
class True
def call(input)
true
end
end
end
Require
require "bsflow/true"
Constructor
BSFlow:True.new # => new_true
Class BSFlow::False
It returns false no matter what input it takes.
Source code:
module BSFlow
class False
def call(input)
false
end
end
end
Require
require "bsflow/false"
Constructor
BSFlow:False.new # => new_false
Class BSFlow::Pass
It passes a value to a proc and returns the unmodified value. So it is a one way ticket for data but it is usefull for sending data to some output stream or queue.
Source code:
module BSFlow
class Pass
def initialize(proc:)
@proc = proc
end
def call(input)
@proc.call(input)
input
end
end
end
Require
require "bsflow/pass"
Constructor
BSFlow:Pass.new(proc: proc) # => new_pass
Paramaters:
- proc - an objects responding on
.call
message with one argument.
Class BSFlow::DropArgs
It calls a proc and returns its output. All arguments are ignored.
Source code:
module BSFlow
class DropArgs
def initialize(proc:)
@proc = proc
end
def call(*args)
@proc.call
end
end
end
Require
require "bsflow/drop_args"
Constructor
BSFlow:DropArgs.new(proc: proc) # => new_args_dropper
Paramaters:
- proc - an objects responding on
.call
message without arguments.
Class BSFlow::Combine
It passes its .call
arguments to each injected sub_proc, then it passes their outputs to injected combine_proc and returns the output.
Source code:
module BSFlow
class Combine
def initialize(*args, combine_proc:, sub_procs: [])
@sub_procs = args + sub_procs
@combine_proc = combine_proc
end
def call(*args)
sub_proc_outputs = []
@sub_procs.each do |sub_proc|
sub_proc_outputs << sub_proc.call(*args)
end
@combine_proc.call(*sub_proc_outputs)
end
end
end
Require
require "bsflow/combine"
Constructor
BSFlow::Combine.new(sub_procs: sub_procs, combine_proc: combine_proc) # => new_combine
# or
BSFlow::Combine.new(*sub_procs, combine_proc: combine_proc) # => new_combine
# or
BSFlow::Combine.new(*first_part_of_sub_procs, sub_procs: rest_of_sub_procs, combine_proc: combine_proc) # => new_combine
Paramaters:
- sub_procs - an array of procs or objects responding on
.call
message. Each of them takes arguments from combine object's call method and return an output. All aoutpus are pased to combine_proc. - combine_procs - a proc or object responding on
.call
message. The output of this proc is the output of the.call
method of the Combine class.
Class BSFlow::UntilTrueLoop
It passes input to condition_proc and if the result is not true it pases the input to loop_proc until the result is true.
Source code:
module BSFlow
class UntilTrueLoop
def initialize(condition_proc:, loop_proc:)
@loop_proc = loop_proc
@condition_proc = condition_proc
end
def call(input)
until @condition_proc.call(input) do
input = @loop_proc.call(input)
end
input
end
end
end
Require
require "bsflow/until_true_loop"
Constructor
BSFlow::UntilTrueLoop.new(condition_proc: condition_proc, loop_proc: loop_proc) # => new_loop
Paramaters:
- condition_proc - proc or object responding on
.call
message with one argument. At the beginning it takes the input from.call
method from UntilTrueLoop class. If an output is truthy the output is returned as the output of.call
message of UntilTrueLoop class. - loop_proc - a proc or objects responding on
.call
message with one argument.
To do features
- Examples in the documentation and source code.
- More classes.
License
The gem is available as open source under the terms of the MIT License.