Invokable: Objects are functions! Treat any Object like a Proc (like Enumerable but for Procs)

Invokable

Objects are functions! Treat any Object, Hashes, Arrays, and Sets as Procs (like Enumerable but for Procs)

Synopsis

require 'invokable'
require 'invokable/hash'

number_names = { 1 => "One", 2 => "Two", 3 => "Three" }
[1, 2, 3, 4].map(&number_names) # => ["One", "Two", "Three", nil]
require 'invokable'
require 'invokable/array'

alpha = ('a'..'z').to_a
[1, 2, 3, 4].map(&alpha) # => ["b", "c", "d", "e"]
require 'invokable'
require 'invokable/set'

favorite_numbers = Set[3, Math::PI]
[1, 2, 3, 4].select(&favorite_numbers) # => [3]
# service objects
require 'invokable'

class GetDataFromSomeService
  include Invokable

  def call(user)
    # do the dirt
  end
end

data_for_user = GetDataFromSomeService.new.memoize # 'memoize' makes a proc that caches results
User.all.map(&data_for_user)
# command objects that enclose state, can be treated as automatically curried functions.
require 'invokable'
require 'invokable/closure'

class TwitterPoster
  include Invokable::Closure

  enclose :model

  def call(user)
    # do the dirt
    ...
    TwitterStatus.new(user, data)
  end
end

TwitterPoster.call(Model.find(1)) # => #<TwitterPoster ...>
TwitterPoster.call(Model.find(1), current_user) # => #<TwitterStatus ...>

# both the class and it's instances can be used any where Procs are.

Model.where(created_at: Date.today).map(&:TwitterPoster) # => [#<TwitterPoster ...>, ...]

Use as much or a little as you need:

require 'invokable'         # loads Invokable module
require 'invokable/closure' # loads Invokable::Closure module
require 'invokable/hash'    # loads hash patch
require 'invokable/array'   # loads array patch
require 'invokable/set'     # loads set patch
require 'invokable/data'    # loads hash and set patches

Why?

A function is a mapping of one value to another with the additional constraint that for the one input value you will always get the same output value. So, conceptually, Ruby Hashes, Arrays, and Sets are all functions. Also, there are many one method objects out there (e.g. Service Objects) that are essentially functions. Why not treat them as such?

See https://github.com/delonnewman/invokable for more information.

1 Like