invokable 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.github/workflows/ruby.yml +20 -0
- data/.gitignore +12 -0
- data/.rspec +3 -0
- data/CHANGELOG.md +7 -0
- data/Gemfile +15 -0
- data/Gemfile.lock +53 -0
- data/LICENSE.txt +21 -0
- data/README.md +154 -0
- data/Rakefile +6 -0
- data/invokable.gemspec +42 -0
- data/lib/invokable.rb +16 -0
- data/lib/invokable/array.rb +10 -0
- data/lib/invokable/command.rb +65 -0
- data/lib/invokable/compose.rb +25 -0
- data/lib/invokable/core.rb +49 -0
- data/lib/invokable/data.rb +2 -0
- data/lib/invokable/hash.rb +12 -0
- data/lib/invokable/method.rb +5 -0
- data/lib/invokable/proc.rb +5 -0
- data/lib/invokable/set.rb +11 -0
- data/lib/invokable/version.rb +3 -0
- metadata +113 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 6dcc085ff857ef0a95578db5f816338c0ade3da6ef4ecb263f86924e4b4e2cfb
|
4
|
+
data.tar.gz: 235f058b7b39b8ff91b8d2580281fad56a388fcea46d19ae3a4bc3657c913d1c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bc8294c008fedd2a69337d886515b8fb9c3a2dd6fea8330b15371ffa9b44db0a5ce3c679badede4e2455230db25845ac723b11aa6736f9b62d690b462f7623e9
|
7
|
+
data.tar.gz: f6cab459416371d902933ee1ef3fd24f935bcc0ad7b6c9e0a9bd261bf95d8736c763ec416b94b063acf52fbc4a08df04586ac4b6bde8c02aedcb47b8f8074ef9
|
@@ -0,0 +1,20 @@
|
|
1
|
+
name: Ruby
|
2
|
+
|
3
|
+
on: [push]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
build:
|
7
|
+
|
8
|
+
runs-on: ubuntu-latest
|
9
|
+
|
10
|
+
steps:
|
11
|
+
- uses: actions/checkout@v2
|
12
|
+
- name: Set up Ruby 2.6
|
13
|
+
uses: actions/setup-ruby@v1
|
14
|
+
with:
|
15
|
+
ruby-version: 2.6.x
|
16
|
+
- name: Build and test with Rake
|
17
|
+
run: |
|
18
|
+
gem install bundler
|
19
|
+
bundle install --jobs 4 --retry 3
|
20
|
+
bundle exec rake
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
source "https://rubygems.org"
|
2
|
+
|
3
|
+
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
|
4
|
+
|
5
|
+
# Specify your gem's dependencies in data-functions.gemspec
|
6
|
+
gemspec
|
7
|
+
|
8
|
+
group :development do
|
9
|
+
gem 'pry'
|
10
|
+
gem 'yard'
|
11
|
+
end
|
12
|
+
|
13
|
+
group :test do
|
14
|
+
gem 'gen-test'
|
15
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
invokable (0.5.0)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
coderay (1.1.2)
|
10
|
+
concurrent-ruby (1.1.5)
|
11
|
+
diff-lcs (1.3)
|
12
|
+
faker (1.9.6)
|
13
|
+
i18n (>= 0.7)
|
14
|
+
gen-test (0.1.1)
|
15
|
+
faker (~> 1.9.6)
|
16
|
+
regexp-examples (~> 1.5.0)
|
17
|
+
i18n (1.8.2)
|
18
|
+
concurrent-ruby (~> 1.0)
|
19
|
+
method_source (0.9.2)
|
20
|
+
pry (0.12.2)
|
21
|
+
coderay (~> 1.1.0)
|
22
|
+
method_source (~> 0.9.0)
|
23
|
+
rake (13.0.1)
|
24
|
+
regexp-examples (1.5.1)
|
25
|
+
rspec (3.9.0)
|
26
|
+
rspec-core (~> 3.9.0)
|
27
|
+
rspec-expectations (~> 3.9.0)
|
28
|
+
rspec-mocks (~> 3.9.0)
|
29
|
+
rspec-core (3.9.1)
|
30
|
+
rspec-support (~> 3.9.1)
|
31
|
+
rspec-expectations (3.9.0)
|
32
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
33
|
+
rspec-support (~> 3.9.0)
|
34
|
+
rspec-mocks (3.9.1)
|
35
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
36
|
+
rspec-support (~> 3.9.0)
|
37
|
+
rspec-support (3.9.2)
|
38
|
+
yard (0.9.24)
|
39
|
+
|
40
|
+
PLATFORMS
|
41
|
+
ruby
|
42
|
+
|
43
|
+
DEPENDENCIES
|
44
|
+
bundler (~> 1.17)
|
45
|
+
gen-test
|
46
|
+
invokable!
|
47
|
+
pry
|
48
|
+
rake (~> 13.0)
|
49
|
+
rspec (~> 3.0)
|
50
|
+
yard
|
51
|
+
|
52
|
+
BUNDLED WITH
|
53
|
+
1.17.3
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2020 Delon Newman
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+

|
2
|
+
[](https://badge.fury.io/rb/invokable)
|
3
|
+
|
4
|
+
# Invokable
|
5
|
+
|
6
|
+
Objects are functions! Treat any Object, Hashes, Arrays, and Sets as Procs (like Enumerable but for Procs)
|
7
|
+
|
8
|
+
## Synopsis
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
require 'invokable'
|
12
|
+
require 'invokable/hash'
|
13
|
+
|
14
|
+
number_names = { 1 => "One", 2 => "Two", 3 => "Three" }
|
15
|
+
[1, 2, 3, 4].map(&number_names) # => ["One", "Two", "Three", nil]
|
16
|
+
```
|
17
|
+
|
18
|
+
```ruby
|
19
|
+
require 'invokable'
|
20
|
+
require 'invokable/array'
|
21
|
+
|
22
|
+
alpha = ('a'..'z').to_a
|
23
|
+
[1, 2, 3, 4].map(&alpha) # => ["b", "c", "d", "e"]
|
24
|
+
```
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
require 'invokable'
|
28
|
+
require 'invokable/set'
|
29
|
+
|
30
|
+
favorite_numbers = Set[3, Math::PI]
|
31
|
+
[1, 2, 3, 4].select(&favorite_numbers) # => [3]
|
32
|
+
```
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
# service objects
|
36
|
+
require 'invokable'
|
37
|
+
|
38
|
+
class GetDataFromSomeService
|
39
|
+
include Invokable
|
40
|
+
|
41
|
+
def call(user)
|
42
|
+
# do the dirt
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
data_for_user = GetDataFromSomeService.new.memoize # 'memoize' makes a proc that caches results
|
47
|
+
User.all.map(&data_for_user)
|
48
|
+
```
|
49
|
+
```ruby
|
50
|
+
# command objects that enclose state, can be treated as automatically curried functions.
|
51
|
+
require 'invokable'
|
52
|
+
require 'invokable/command'
|
53
|
+
|
54
|
+
class TwitterPoster
|
55
|
+
include Invokable::Command
|
56
|
+
|
57
|
+
enclose do |model|
|
58
|
+
@model = model
|
59
|
+
end
|
60
|
+
|
61
|
+
def call(user)
|
62
|
+
# do the dirt
|
63
|
+
...
|
64
|
+
TwitterStatus.new(user, data)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
TwitterPoster.call(Model.find(1)) # => #<TwitterPoster ...>
|
69
|
+
TwitterPoster.call(Model.find(1), current_user) # => #<TwitterStatus ...>
|
70
|
+
|
71
|
+
# both the class and it's instances can be used any where Procs are.
|
72
|
+
|
73
|
+
Model.where(created_at: Date.today).map(&:TwitterPoster) # => [#<TwitterPoster ...>, ...]
|
74
|
+
```
|
75
|
+
|
76
|
+
Use as much or a little as you need:
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
require 'invokable' # loads Invokable module
|
80
|
+
require 'invokable/command' # loads Invokable::Command module
|
81
|
+
require 'invokable/hash' # loads hash patch
|
82
|
+
require 'invokable/array' # loads array patch
|
83
|
+
require 'invokable/set' # loads set patch
|
84
|
+
require 'invokable/data' # loads hash and set patches
|
85
|
+
```
|
86
|
+
|
87
|
+
## Why?
|
88
|
+
|
89
|
+
A function is a mapping of one value to another with the additional constraint that for the one input value you will
|
90
|
+
always get the same output value. So, conceptually, Ruby Hashes, Arrays, and Sets are all functions. Also, there are
|
91
|
+
many one method objects out there (e.g. Service Objects) that are essentially functions. Why not treat them as such?
|
92
|
+
|
93
|
+
## Installation
|
94
|
+
|
95
|
+
Add this line to your application's Gemfile:
|
96
|
+
|
97
|
+
```ruby
|
98
|
+
gem 'invokable'
|
99
|
+
```
|
100
|
+
|
101
|
+
And then execute:
|
102
|
+
|
103
|
+
> bundle
|
104
|
+
|
105
|
+
Or install it yourself as:
|
106
|
+
|
107
|
+
> gem install invokable
|
108
|
+
|
109
|
+
## API
|
110
|
+
|
111
|
+
### `to_proc => Proc`
|
112
|
+
|
113
|
+
```ruby
|
114
|
+
hash = { a: 1, b, 2 }
|
115
|
+
hash.class # => Hash
|
116
|
+
hash.to_proc.class # => Proc
|
117
|
+
[:a, :b].map(&hash) # => [1, 2]
|
118
|
+
```
|
119
|
+
|
120
|
+
Convert an object into a proc. When the `Invokable` module is included in a class it will do this by
|
121
|
+
returning a proc that passes it's arguments to the object's `call` method. When `invokable/data` is
|
122
|
+
loaded `Hash#call` is mapped to `Hash#dig`, `Array#call` is mapped to `Array#at`, and `Set#call`
|
123
|
+
is mapped to `Set#include?`.
|
124
|
+
|
125
|
+
### `curry(arity = nil) => Proc`
|
126
|
+
|
127
|
+
Returns a curried proc. If the `arity` is given, it determines the number of arguments.
|
128
|
+
(see [Proc#curry](https://ruby-doc.org/core-2.7.0/Proc.html#method-i-curry)).
|
129
|
+
|
130
|
+
### `memoize => Proc`
|
131
|
+
|
132
|
+
Returns a memoized proc, that is, a proc that caches it's return values by it's arguments.
|
133
|
+
|
134
|
+
### `<<(invokable) => Proc`
|
135
|
+
|
136
|
+
Returns a proc that is a composition of this invokable and the given invokable.
|
137
|
+
|
138
|
+
### `>>(invokable) => Proc`
|
139
|
+
|
140
|
+
Returns a proc that is a composition of this invokable and the given invokable.
|
141
|
+
|
142
|
+
## See Also
|
143
|
+
|
144
|
+
- [Closures and Objects are Equivalent](http://wiki.c2.com/?ClosuresAndObjectsAreEquivalent)
|
145
|
+
- [Clojure](https://clojure.org)
|
146
|
+
- [Arc](http://www.arclanguage.org)
|
147
|
+
|
148
|
+
## TODO
|
149
|
+
|
150
|
+
- benchmark Invokable#to_proc
|
151
|
+
|
152
|
+
## License
|
153
|
+
|
154
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/invokable.gemspec
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
lib = File.expand_path("../lib", __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require "invokable/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "invokable"
|
7
|
+
spec.version = Invokable::VERSION
|
8
|
+
spec.authors = ["Delon Newman"]
|
9
|
+
spec.email = ["contact@delonnewman.name"]
|
10
|
+
|
11
|
+
spec.summary = %q{Objects are functions! Treat any Object, Hashes, Arrays and Sets as Procs (like Enumerable but for Proc-like objects)}
|
12
|
+
spec.description = spec.summary
|
13
|
+
spec.homepage = "https://github.com/delonnewman/invokable"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
17
|
+
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
18
|
+
if spec.respond_to?(:metadata)
|
19
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
20
|
+
|
21
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
22
|
+
spec.metadata["source_code_uri"] = spec.homepage
|
23
|
+
spec.metadata["changelog_uri"] = "#{spec.homepage}#changelog"
|
24
|
+
spec.metadata["documentation_uri"] = "https://www.rubydoc.info/gems/invokable"
|
25
|
+
else
|
26
|
+
raise "RubyGems 2.0 or newer is required to protect against " \
|
27
|
+
"public gem pushes."
|
28
|
+
end
|
29
|
+
|
30
|
+
# Specify which files should be added to the gem when it is released.
|
31
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
32
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
33
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
34
|
+
end
|
35
|
+
spec.bindir = "bin"
|
36
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
37
|
+
spec.require_paths = ["lib"]
|
38
|
+
|
39
|
+
spec.add_development_dependency "bundler", "~> 1.17"
|
40
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
41
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
42
|
+
end
|
data/lib/invokable.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'invokable/version'
|
2
|
+
require 'invokable/core'
|
3
|
+
require 'invokable/compose'
|
4
|
+
|
5
|
+
# TODO: make use of Gem::Version
|
6
|
+
if RUBY_VERSION.split('.').take(2).join('.').to_f < 2.6
|
7
|
+
require 'invokable/proc'
|
8
|
+
require 'invokable/method'
|
9
|
+
end
|
10
|
+
|
11
|
+
module Invokable
|
12
|
+
def self.included(base)
|
13
|
+
base.include(Invokable::Core)
|
14
|
+
base.include(Invokable::Compose)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require_relative 'core'
|
2
|
+
|
3
|
+
# Extend core Array object by aliasing it's `[]` method as `call`,
|
4
|
+
# and including the `Invokable` module.
|
5
|
+
#
|
6
|
+
# @see https://ruby-doc.org/core-2.7.0/Array.html#method-i-5B-5D Array#[]
|
7
|
+
class Array
|
8
|
+
include Invokable::Core
|
9
|
+
alias call []
|
10
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Invokable
|
2
|
+
# Treat "Command Objects" as curried functions
|
3
|
+
#
|
4
|
+
# @see https://ruby-doc.org/core-2.7.0/Proc.html#method-i-curry Proc#curry
|
5
|
+
#
|
6
|
+
# @version 0.5.0
|
7
|
+
module Command
|
8
|
+
def self.included(klass)
|
9
|
+
klass.include(Invokable)
|
10
|
+
klass.extend(Invokable::Core)
|
11
|
+
klass.extend(Invokable::Compose)
|
12
|
+
klass.extend(ClassMethods)
|
13
|
+
end
|
14
|
+
|
15
|
+
module ClassMethods
|
16
|
+
# Return the "total" arity of the class (i.e. the arity of the initializer and the arity of the call method)
|
17
|
+
#
|
18
|
+
# @version 0.5.0
|
19
|
+
# @see https://ruby-doc.org/core-2.7.1/Proc.html#method-i-arity Proc#arity
|
20
|
+
# @see initializer_arity
|
21
|
+
#
|
22
|
+
# @return [Integer]
|
23
|
+
def arity
|
24
|
+
initializer_arity + instance_method(:call).arity
|
25
|
+
end
|
26
|
+
|
27
|
+
# Return the arity of the initializer
|
28
|
+
#
|
29
|
+
# @version 0.5.0
|
30
|
+
# @see arity
|
31
|
+
#
|
32
|
+
# @return [Integer]
|
33
|
+
def initializer_arity
|
34
|
+
@initializer ? @initializer.arity : 0
|
35
|
+
end
|
36
|
+
|
37
|
+
# To specify any enclosed state
|
38
|
+
def enclose(&block)
|
39
|
+
raise 'A block is required' if block.nil?
|
40
|
+
|
41
|
+
@initializer = block
|
42
|
+
define_method :initialize, &block
|
43
|
+
end
|
44
|
+
|
45
|
+
# Handle automatic currying--will accept either the initializer arity or the total arity of the class. If
|
46
|
+
# the initializer arity is used return a class instance. If the total arity is used instantiate the class
|
47
|
+
# and return the results of the `call` method.
|
48
|
+
#
|
49
|
+
# @version 0.5.0
|
50
|
+
# @see arity
|
51
|
+
# @see initializer_arity
|
52
|
+
def call(*args)
|
53
|
+
if args.length == initializer_arity
|
54
|
+
new(*args)
|
55
|
+
elsif args.length == arity
|
56
|
+
init_args = args.slice(0, initializer_arity)
|
57
|
+
call_args = args.slice(initializer_arity, args.length)
|
58
|
+
new(*init_args).call(*call_args)
|
59
|
+
else
|
60
|
+
raise "Wrong number of arguments expected #{initializer_arity} or #{arity}, got: #{args.length}"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Invokable
|
2
|
+
module Compose
|
3
|
+
# Return a proc that is the composition of this invokable and the given `invokable`.
|
4
|
+
# The returned proc takes a variable number of arguments, calls `invokable` with
|
5
|
+
# them then calls this proc with the result.
|
6
|
+
#
|
7
|
+
# @return [Proc]
|
8
|
+
def <<(invokable)
|
9
|
+
Proc.new do |*args|
|
10
|
+
call(invokable.call(*args))
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# Return a proc that is the composition of this invokable and the given `invokable`.
|
15
|
+
# The returned proc takes a variable number of arguments, calls `invokable` with
|
16
|
+
# them then calls this proc with the result.
|
17
|
+
#
|
18
|
+
# @return [Proc]
|
19
|
+
def >>(invokable)
|
20
|
+
Proc.new do |*args|
|
21
|
+
invokable.call(call(*args))
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Invokable
|
2
|
+
module Core
|
3
|
+
# If object responds to `call` convert into a Proc forwards it's arguments along to `call`.
|
4
|
+
#
|
5
|
+
# @see https://ruby-doc.org/core-2.7.0/Proc.html#method-i-call Proc#call
|
6
|
+
# @return [Proc]
|
7
|
+
def to_proc
|
8
|
+
if respond_to?(:call)
|
9
|
+
# TODO: Would method(:call) be more performant? We need benchmarks.
|
10
|
+
Proc.new do |*args|
|
11
|
+
call(*args)
|
12
|
+
end
|
13
|
+
else
|
14
|
+
raise "Don't know how to convert #{self.inspect} into a Proc"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# Return a curried proc. If the optional `arity` argument is given, it determines the number of arguments.
|
19
|
+
# A curried proc receives some arguments. If a sufficient number of arguments are supplied, it passes the
|
20
|
+
# supplied arguments to the original proc and returns the result. Otherwise, returns another curried proc
|
21
|
+
# that takes the rest of arguments.
|
22
|
+
#
|
23
|
+
# @see https://ruby-doc.org/core-2.7.0/Proc.html#method-i-curry Proc#curry
|
24
|
+
# @param arity [Integer]
|
25
|
+
# @return [Proc]
|
26
|
+
def curry(arity = nil)
|
27
|
+
to_proc.curry(arity)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Return a memoized proc, that is, a proc that caches it's return values by it's arguments.
|
31
|
+
#
|
32
|
+
# @return [Proc]
|
33
|
+
def memoize
|
34
|
+
Proc.new do |*args|
|
35
|
+
@memo ||= {}
|
36
|
+
@memo[args.hash] ||= call(*args)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Return the arity (i.e. the number of arguments) of the `call` method.
|
41
|
+
#
|
42
|
+
# @version 0.5.0
|
43
|
+
# @see https://ruby-doc.org/core-2.7.1/Proc.html#method-i-arity Proc#arity
|
44
|
+
# @return [Integer]
|
45
|
+
def arity
|
46
|
+
method(:call).arity
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require_relative 'core'
|
2
|
+
|
3
|
+
# Extend core Hash object by aliasing it's `dig` method as `call`,
|
4
|
+
# and including the `Invokable` module.
|
5
|
+
#
|
6
|
+
# @see https://ruby-doc.org/core-2.7.0/Hash.html#method-i-dig Hash#dig
|
7
|
+
class Hash
|
8
|
+
if RUBY_VERSION.split('.').take(2).join('.').to_f < 2.7
|
9
|
+
include Invokable::Core
|
10
|
+
alias call dig
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'set'
|
2
|
+
require_relative 'core'
|
3
|
+
|
4
|
+
# Extend stdlib Set object by aliasing it's `include?` method as `call`,
|
5
|
+
# and including the `Invokable` module.
|
6
|
+
#
|
7
|
+
# @see https://ruby-doc.org/stdlib-2.7.0/libdoc/set/rdoc/Set.html#method-i-include-3F Set#include?
|
8
|
+
class Set
|
9
|
+
include Invokable::Core
|
10
|
+
alias call include?
|
11
|
+
end
|
metadata
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: invokable
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.5.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Delon Newman
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-07-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.17'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.17'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '13.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '13.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
description: Objects are functions! Treat any Object, Hashes, Arrays and Sets as Procs
|
56
|
+
(like Enumerable but for Proc-like objects)
|
57
|
+
email:
|
58
|
+
- contact@delonnewman.name
|
59
|
+
executables: []
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- ".github/workflows/ruby.yml"
|
64
|
+
- ".gitignore"
|
65
|
+
- ".rspec"
|
66
|
+
- CHANGELOG.md
|
67
|
+
- Gemfile
|
68
|
+
- Gemfile.lock
|
69
|
+
- LICENSE.txt
|
70
|
+
- README.md
|
71
|
+
- Rakefile
|
72
|
+
- invokable.gemspec
|
73
|
+
- lib/invokable.rb
|
74
|
+
- lib/invokable/array.rb
|
75
|
+
- lib/invokable/command.rb
|
76
|
+
- lib/invokable/compose.rb
|
77
|
+
- lib/invokable/core.rb
|
78
|
+
- lib/invokable/data.rb
|
79
|
+
- lib/invokable/hash.rb
|
80
|
+
- lib/invokable/method.rb
|
81
|
+
- lib/invokable/proc.rb
|
82
|
+
- lib/invokable/set.rb
|
83
|
+
- lib/invokable/version.rb
|
84
|
+
homepage: https://github.com/delonnewman/invokable
|
85
|
+
licenses:
|
86
|
+
- MIT
|
87
|
+
metadata:
|
88
|
+
allowed_push_host: https://rubygems.org
|
89
|
+
homepage_uri: https://github.com/delonnewman/invokable
|
90
|
+
source_code_uri: https://github.com/delonnewman/invokable
|
91
|
+
changelog_uri: https://github.com/delonnewman/invokable#changelog
|
92
|
+
documentation_uri: https://www.rubydoc.info/gems/invokable
|
93
|
+
post_install_message:
|
94
|
+
rdoc_options: []
|
95
|
+
require_paths:
|
96
|
+
- lib
|
97
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '0'
|
107
|
+
requirements: []
|
108
|
+
rubygems_version: 3.0.6
|
109
|
+
signing_key:
|
110
|
+
specification_version: 4
|
111
|
+
summary: Objects are functions! Treat any Object, Hashes, Arrays and Sets as Procs
|
112
|
+
(like Enumerable but for Proc-like objects)
|
113
|
+
test_files: []
|