invocations 0.2.6

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 212878a412f9d0078de6d2a13192a8d4867d72a3ec64c1a5680dd1e4bfd03acf
4
+ data.tar.gz: e9bf132d50b08da294099cb995ede79dadd9fc7304d2ab6fb8ab11839dfd49d4
5
+ SHA512:
6
+ metadata.gz: da1fbe8a35ece0b67dbaebb87e300c970f4319f52532b922e3813ffb917f996f353632d43244e8278c4ff3894a8148bd855c80242a97f424945acc681117d99c
7
+ data.tar.gz: dae0dcfe98e1653f5e068ace7dd986ceb43eaaf61857f8e4139e7b7c878f47c0ad8e5e2faf0ff85faa01b8d1c561af204aeca3c701868928791d2735f28857a4
Binary file
Binary file
@@ -0,0 +1,57 @@
1
+
2
+ # Created by https://www.gitignore.io/api/ruby
3
+
4
+ ### Ruby ###
5
+ *.gem
6
+ *.rbc
7
+ /.config
8
+ /coverage/
9
+ /InstalledFiles
10
+ /pkg/
11
+ /spec/reports/
12
+ /spec/examples.txt
13
+ /test/tmp/
14
+ /test/version_tmp/
15
+ /tmp/
16
+
17
+ # Used by dotenv library to load environment variables.
18
+ # .env
19
+
20
+ ## Specific to RubyMotion:
21
+ .dat*
22
+ .repl_history
23
+ build/
24
+ *.bridgesupport
25
+ build-iPhoneOS/
26
+ build-iPhoneSimulator/
27
+
28
+ ## Specific to RubyMotion (use of CocoaPods):
29
+ #
30
+ # We recommend against adding the Pods directory to your .gitignore. However
31
+ # you should judge for yourself, the pros and cons are mentioned at:
32
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
33
+ #
34
+ # vendor/Pods/
35
+
36
+ ## Documentation cache and generated files:
37
+ /.yardoc/
38
+ /_yardoc/
39
+ /doc/
40
+ /rdoc/
41
+
42
+ ## Environment normalization:
43
+ /.bundle/
44
+ /vendor/bundle
45
+ /lib/bundler/man/
46
+
47
+ # for a library or gem, you might want to ignore these files since the code is
48
+ # intended to run in multiple environments; otherwise, check them in:
49
+ # Gemfile.lock
50
+ # .ruby-version
51
+ # .ruby-gemset
52
+
53
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
54
+ .rvmrc
55
+
56
+
57
+ # End of https://www.gitignore.io/api/ruby
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,22 @@
1
+
2
+ The MIT License (MIT)
3
+ Copyright © 2018 Chris Olstrom <chris@olstrom.com>
4
+ Copyright © 2018 SUSE LLC
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the “Software”), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in
14
+ all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ THE SOFTWARE.
@@ -0,0 +1,128 @@
1
+ #+TITLE: Invocations
2
+ #+LATEX: \pagebreak
3
+
4
+ * Overview
5
+
6
+ ~Invocations~ are better partial functions for Ruby, because sometimes
7
+ =Proc#curry= just isn't enough.
8
+
9
+ * What problem does this solve?
10
+
11
+ Partial function evaluation is a very useful tool, but understanding the state
12
+ carried by a curried =Proc= is often cumbersome and unintuitive.
13
+
14
+ * How does Invocations address this problem?
15
+
16
+ ~Invocations~ provides a single class: the =Invocation=. It functions as a
17
+ drop-in alternative to a =Proc=, with a few notable improvements (none of
18
+ which break compatibility):
19
+
20
+ - An =Invocation= is implicitly self-currying. Which is to say that if you
21
+ call it without all the parameters it requires, it simply returns an
22
+ =Invocation= that requires the missing parameters.
23
+ - An =Invocation= allows non-keyword arguments to be given as keywords.
24
+ - An =Invocation= allows arguments to be given out of order, as keyword
25
+ arguments.
26
+ - An =Invocation= has several methods for inspection, including ones for
27
+ listing the missing arguments, identifying keyword inferences, explaining
28
+ how the underlying function will be called, and reporting internal state.
29
+
30
+ * Installation
31
+
32
+ #+BEGIN_SRC shell
33
+ gem install invocations
34
+ #+END_SRC
35
+
36
+ * How can I start using this majestic tool?
37
+
38
+ An =Invocation= is a drop-in alternative to =Proc=, or =lambda=. You can use
39
+ it as an explicit =&block=, etc. As a result, it's very easy to adapt existing
40
+ code to use it.
41
+
42
+ Let's lay out a simple function that will serve as our example, going forward.
43
+
44
+ This =power= function takes two arguments, =n= (a number) and =e= (an
45
+ exponent) and returns the result of raising =n= to =e=:
46
+
47
+ #+BEGIN_SRC ruby
48
+ lambda_power = lambda { |n, e| n ** e }
49
+ #+END_SRC
50
+
51
+ Now, this is somewhat contrived, because I've deliberately defined the
52
+ arguments in the least convenient order, for illustrative purposes.
53
+
54
+ The equivalent =Invocation= would be:
55
+
56
+ #+BEGIN_SRC ruby
57
+ invoke_power = Invocation.new { |n, e| n ** e }
58
+ #+END_SRC
59
+
60
+ ~Invocations~ includes an optional =Refinement= for that brings the syntax
61
+ more in line with =proc= and =lambda=:
62
+
63
+ #+BEGIN_SRC ruby
64
+ using Invocations
65
+ invoke_power = invocation { |n, e| n ** e }
66
+ #+END_SRC
67
+
68
+ Calling either of these is the same:
69
+
70
+ #+BEGIN_SRC ruby
71
+ lambda_power.(5, 2) #=> 25
72
+ invoke_power.(5, 2) #=> 25
73
+ #+END_SRC
74
+
75
+ Let's say we wanted to define =lambda_square= and =lambda_cube= functions,
76
+ that do what their names imply:
77
+
78
+ #+BEGIN_SRC ruby
79
+ lambda_square = lambda { |n| lambda_power.(n, 2) }
80
+ lambda_cube = lambda { |n| lambda_power.(n, 3) }
81
+ #+END_SRC
82
+
83
+ The order of the arguments to =lambda_power= makes these definitions more
84
+ awkward. If instead, we had defined it like so:
85
+
86
+ #+BEGIN_SRC ruby
87
+ lambda_power = lambda { |e, n| n ** e }.curry
88
+ #+END_SRC
89
+
90
+ Then we could have done this:
91
+
92
+ #+BEGIN_SRC ruby
93
+ lambda_square = lambda_power.(2)
94
+ lambda_cube = lambda_power.(3)
95
+ #+END_SRC
96
+
97
+ That said, we don't define every function we use. Often we use the functions
98
+ provided by a library, and if those have inconvenient argument ordering, too
99
+ bad.
100
+
101
+ If we had been using an =Invocation=, we could have done this:
102
+
103
+ #+BEGIN_SRC ruby
104
+ invoke_square = invoke_power.(e: 2)
105
+ invoke_cube = invoke_power.(e: 3)
106
+ #+END_SRC
107
+
108
+ ** Wait what? Those weren't keyword arguments.
109
+
110
+ True, but the block parameters have names. Since it is a =SyntaxError= for a
111
+ block to have two parameters with the same name, an =Invocation= can Do The
112
+ Right Thing.
113
+
114
+ * Explore It!
115
+
116
+ ~Invocations~ really shines when used with a great REPL like [[https://github.com/pry/pry][pry]].
117
+
118
+ I've uploaded a short screencast [[https://asciinema.org/a/DW4ctct8Nkx1qdwjmOF9Eyw4O][here]] that demonstrates the sort of
119
+ information an =Invocation= provides (using the example scenario above).
120
+
121
+ * License
122
+
123
+ ~Invocations~ is available under the [[https://tldrlegal.com/license/mit-license][MIT License]]. See ~LICENSE.txt~ for the
124
+ full text.
125
+
126
+ * Contributors
127
+
128
+ - [[https://colstrom.github.io/][Chris Olstrom]] | [[mailto:chris@olstrom.com][e-mail]] | [[https://twitter.com/ChrisOlstrom][Twitter]]
@@ -0,0 +1,23 @@
1
+ Gem::Specification.new do |gem|
2
+ tag = `git describe --tags --abbrev=0`.chomp
3
+
4
+ gem.name = 'invocations'
5
+ gem.homepage = 'https://github.com/colstrom/invocations'
6
+ gem.summary = 'Drop-in alternative to procs and lambdas.'
7
+
8
+ gem.version = "#{tag}"
9
+ gem.licenses = ['MIT']
10
+ gem.authors = ['Chris Olstrom']
11
+ gem.email = 'chris@olstrom.com'
12
+
13
+ gem.cert_chain = ['trust/certificates/colstrom.pem']
14
+ gem.signing_key = File.expand_path ENV.fetch 'GEM_SIGNING_KEY'
15
+
16
+ gem.files = `git ls-files -z`.split("\x0")
17
+ gem.test_files = `git ls-files -z -- {test,spec,features}/*`.split("\x0")
18
+ gem.executables = `git ls-files -z -- bin/*`.split("\x0").map { |f| File.basename(f) }
19
+
20
+ gem.require_paths = ['lib']
21
+
22
+ gem.required_ruby_version = '~> 2.3.0' # Explicit Non-Support of Unsupported Ruby Versions
23
+ end
@@ -0,0 +1,17 @@
1
+
2
+ # -*- ruby -*-
3
+
4
+ require_relative 'invocations/invocation'
5
+
6
+ # This module refines Kernel, adding "invocation" and "Invocation" as methods.
7
+ module Invocations
8
+ refine Kernel do
9
+ # Creates a new Invocation with the provided parameters
10
+ def invocation(*rest, **keyrest, &block)
11
+ ::Invocation.new(*rest, **keyrest, &block)
12
+ end
13
+
14
+ alias_method :Invocation, :invocation
15
+ end
16
+ end
17
+
@@ -0,0 +1,253 @@
1
+
2
+ # -*- ruby -*-
3
+
4
+ # Invocations are drop-in replacements for other functions (such as
5
+ # procs/blocks, lambdas, methods, etc).
6
+ #
7
+ # They differ in that they are self-currying, allow partial evaluation with
8
+ # arbitrary argument ordering, and allow non-keyword arguments to be given as
9
+ # keywords.
10
+ #
11
+ class Invocation
12
+ %i(call yield []).each { |name| singleton_class.alias_method name, :new }
13
+
14
+ # Creates a new Invocation.
15
+ #
16
+ # @param callable [#call] a proc-like object
17
+ #
18
+ # @raise [ArgumentError] if neither a callable object nor a block is provided.
19
+ #
20
+ # @return [Invocation] a new instance of Invocation
21
+ #
22
+ def initialize(callable = nil, *rest, **state, &block)
23
+ raise ::ArgumentError, "#{self.class}##{__callee__} requires a callable object or a block" unless (callable.respond_to?(:call) || block)
24
+
25
+ if callable.respond_to? :call
26
+ @function = callable
27
+ @block = block
28
+ else
29
+ @function = block
30
+ end
31
+
32
+ @state = state
33
+ @rest = rest
34
+
35
+ %i(required optional inferences unassigned arguments keywords).each { |method| send method }
36
+
37
+ self
38
+ end
39
+
40
+ attr_reader :function, :state
41
+
42
+ # Which parameters are required?
43
+ #
44
+ # @return [Array<Symbol>] the required parameters of the function
45
+ #
46
+ def required
47
+ @required ||= (
48
+ required_arguments = function_parameters(:req)
49
+ required_keywords = function_parameters(:keyreq)
50
+ needed = function_arity - (required_arguments.length + (required_keywords.length > 0 ? 1 : 0))
51
+
52
+ @required = function_parameters(:opt, :key).take(needed) + required_arguments + required_keywords
53
+ )
54
+ end
55
+
56
+ # Which parameters are optional?
57
+ #
58
+ # @return [Array<Symbol>] the optional parameters of the function
59
+ #
60
+ def optional
61
+ @optional ||= function_parameters(:opt, :key)
62
+ .drop(function_arity - function_parameters(:req).length)
63
+ end
64
+
65
+ # Which parameters can be inferred from arguments?
66
+ #
67
+ # @return [Hash<Symbol, Object>] the inferred association of non-keyword
68
+ # arguments to parameter names.
69
+ #
70
+ def inferences
71
+ @inferences ||= if @rest.empty?
72
+ {}
73
+ else
74
+ (function_parameters(:req, :opt) - @state.keys)
75
+ .map
76
+ .with_index { |argument, index| [argument, @rest[index]] if index < @rest.length }
77
+ .compact
78
+ .to_h
79
+ end
80
+ end
81
+
82
+ # Which arguments are not assigned to known parameters?
83
+ #
84
+ # @return [Array] the arguments that are not assigned to parameters.
85
+ #
86
+ def unassigned
87
+ @unassigned ||= @rest.drop(inferences.length)
88
+ end
89
+
90
+ # Which parameters have been provided?
91
+ #
92
+ # @return [Hash<Symbol, Object>] all known parameters provided for the function.
93
+ #
94
+ def known
95
+ @known ||= @state.merge(inferences)
96
+ end
97
+
98
+ # Which parameters are missing?
99
+ #
100
+ # @return [Array<Symbol>] the names of any missing parameters.
101
+ def missing
102
+ @missing ||= required - known.keys
103
+ end
104
+
105
+ # What are the arguments?
106
+ #
107
+ # @return [Array] the provided arguments for the function.
108
+ def arguments
109
+ @arguments ||= function_parameters(:req, :opt, :rest)
110
+ .map { |argument| known[argument] }
111
+ end
112
+
113
+ # What are the keywords?
114
+ #
115
+ # @return [Hash<Symbol, Object>] the provided keywords for the functino.
116
+ #
117
+ def keywords
118
+ @keywords ||= function_parameters(:keyreq, :key, :keyrest)
119
+ .map { |keyword| [keyword, known[keyword]] if known.key?(keyword) }
120
+ .compact
121
+ .to_h
122
+ end
123
+
124
+ # How will the function be called?
125
+ #
126
+ # @return Array the list of arguments that will be used to call the function.
127
+ #
128
+ def invocation(*rest, **keyrest)
129
+ @invocation ||= [*[*arguments, *unassigned].compact, *rest, *[**keywords.merge(keyrest)].reject(&:empty?)]
130
+ end
131
+
132
+ # Is the function ready to be called?
133
+ #
134
+ # @return [Boolean] if this Invocation has all required parameters specified.
135
+ #
136
+ def prepared?
137
+ missing.empty?
138
+ end
139
+
140
+ # Prepares an Invocation, without calling it.
141
+ #
142
+ # @return [Invocation] a new Invocation populated with the parameters given.
143
+ #
144
+ def prepare(*rest, **keyrest, &block)
145
+ self.class.new(@function, *[*unassigned, *rest], **known.merge(keyrest), &(block || @block))
146
+ end
147
+
148
+ # Prepares an Invocation, and invokes it if able.
149
+ #
150
+ # If the provided parameters produce a properly prepared Invocation, it will
151
+ # be invoked. Otherwise, it will be returned.
152
+ #
153
+ # @note This is very similar to how #call works with a curried Proc.
154
+ #
155
+ def call(*rest, **keyrest, &block)
156
+ if block || [rest, keyrest].all?(&:empty?)
157
+ prepared? ? invoke : self
158
+ else
159
+ function = prepare(*rest, **keyrest, &block)
160
+ function.prepared? ? function.send(:invoke) : function
161
+ end
162
+ end
163
+
164
+ alias [] call
165
+ alias yield call
166
+
167
+ # How many additional parameters are needed?
168
+ #
169
+ # @return [Integer] the number of required parameters.
170
+ #
171
+ # @note when multiple keyword parameters are required, they count as one
172
+ # parameter. This is consistent with other Ruby functions (Proc, etc).
173
+ #
174
+ def arity
175
+ @arity ||= (
176
+ required_keywords = function_parameters(:keyreq)
177
+ missing_keywords = required_keywords - known.keys
178
+ (missing - required_keywords).length + (missing_keywords.length > 0 ? 1 : 0)
179
+ )
180
+ end
181
+
182
+ # Converts the Invocation into a Proc
183
+ #
184
+ # @return [Proc] a Proc that calls the Invocation with any parameters given.
185
+ #
186
+ def to_proc
187
+ proc { |*rest, **keyrest, &block| self.(*rest, **keyrest, &block) }
188
+ end
189
+
190
+ # Converts the Invocation into a curried Proc.
191
+ #
192
+ # @return [Proc] a Proc, curried with the arity of the Invocation.
193
+ #
194
+ def curry(n = arity)
195
+ to_proc.curry(n)
196
+ end
197
+
198
+ # Is the Invocation a lambda?
199
+ #
200
+ # @return [false] false, always.
201
+ #
202
+ # @note An Invocation is not a lambda, as it does not handle arguments
203
+ # strictly. It is semantically much more proc-like.
204
+ #
205
+ def lambda?
206
+ false
207
+ end
208
+
209
+ # Which parameters have not been provided?
210
+ #
211
+ # @return [Array<Symbol, Symbol>] the remaining parameters of the function.
212
+ #
213
+ def parameters
214
+ @function.parameters.reject { |_, name| known.keys.include? name }
215
+ end
216
+
217
+ ####################
218
+ # Internal Methods #
219
+ ####################
220
+
221
+ private
222
+
223
+ # Invokes the function.
224
+ #
225
+ # @note This is used internally to call the function. A return cannot be
226
+ # specified, because it depends entirely on the function this Invocation was
227
+ # created with.
228
+ #
229
+ def invoke(*rest, **keyrest, &block)
230
+ @function.(*invocation(*rest, **keyrest), &(block || @block))
231
+ end
232
+
233
+ # How many parameters does the function require?
234
+ #
235
+ # @return [Integer] The arity of the initial function.
236
+ #
237
+ # @note this is for internal use, and is *not* strictly equivalent to
238
+ # function.arity. For example, it always returns a non-negative value.
239
+ #
240
+ def function_arity
241
+ @function.arity.positive? ? @function.arity : @function.arity.succ.abs
242
+ end
243
+
244
+ # What are the names of the parameters of certain types?
245
+ #
246
+ # @return [Array<Symbol>] the names of parameters matching the given types.
247
+ #
248
+ def function_parameters(*types)
249
+ @function.parameters
250
+ .select { |type, _| types.include? type }
251
+ .flat_map(&:last)
252
+ end
253
+ end
@@ -0,0 +1,24 @@
1
+ #! /usr/bin/env ruby
2
+ # -*- ruby -*-
3
+
4
+ require_relative '../lib/invocations'
5
+
6
+ class Invocation
7
+ def self.test
8
+ {
9
+ '&lambda' => (self.new(&lambda { |am1, am2, ao = nil, *ar, km1:, km2:, ko: nil, **kr| [am1, am2, ao, ar, km1, km2, ko, kr] })),
10
+ 'lambda' => (self.new(lambda { |am1, am2, ao = nil, *ar, km1:, km2:, ko: nil, **kr| [am1, am2, ao, ar, km1, km2, ko, kr] })),
11
+ '&proc' => (self.new(&proc { |am1, am2, ao = nil, *ar, km1:, km2:, ko: nil, **kr| [am1, am2, ao, ar, km1, km2, ko, kr] })),
12
+ 'proc' => (self.new(proc { |am1, am2, ao = nil, *ar, km1:, km2:, ko: nil, **kr| [am1, am2, ao, ar, km1, km2, ko, kr] })),
13
+ '&block' => (self.new { |am1, am2, ao = nil, *ar, km1:, km2:, ko: nil, **kr| [am1, am2, ao, ar, km1, km2, ko, kr] }),
14
+ }
15
+ end
16
+ end
17
+
18
+ abort unless 1 == Invocation
19
+ .test
20
+ .map { |style, function| [style, function.(1).(2).(3).(4, 5).(km1: 6).(km2: 7)] }
21
+ .to_h
22
+ .values
23
+ .uniq
24
+ .length
@@ -0,0 +1,25 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIENDCCApygAwIBAgIBATANBgkqhkiG9w0BAQsFADAiMSAwHgYDVQQDDBdjaHJp
3
+ cy9EQz1vbHN0cm9tL0RDPWNvbTAeFw0xODAzMTUxODMxMTdaFw0xOTAzMTUxODMx
4
+ MTdaMCIxIDAeBgNVBAMMF2NocmlzL0RDPW9sc3Ryb20vREM9Y29tMIIBojANBgkq
5
+ hkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAp31YmQvpMuQSlgX22B++/rxl4p4LYyaq
6
+ cDDbi8DBro9cm2H60lbpCuAUALiED2CagZEK0vel5W8AnZhhns0OEYAlpQtBSJtN
7
+ 8P/jlNYruuY26aVhfHfyA5j1n7tVecJz3i/awEPGC3zuTfvUq7Ahn5czOy+hIm4M
8
+ epee881dqnJlXjzTX/TKFYQa9tYj4bhsjfJOV+EDMcao/DE3vmNcBKH8XFVv/wQe
9
+ MGC7VY5zBwow00AkCicNmIr0Psy5hLvqphJ/E3Eiu4UpXhiBfM0z7xiBPoPMBqOx
10
+ r1RzgfKm/JbDO7leFmrEi8hLofyMmbuGvrSTE274vS4EnKaW6OtK7QM5R+jOJZbd
11
+ 67KUgSw+LdHNwu8xCuuQOdKPeSfWdNz94KAdczjzHdXUl/SpfmTuN/D+BCZjTxSo
12
+ F1kACSU6uGTBFKZy35XK+yqeny/1l6xRs6j+cON+LSRMKYSt7jdLcKQVk5wH2xLo
13
+ 83njwnumFxKhiWu0oaT5dlDCtyYM85j9AgMBAAGjdTBzMAkGA1UdEwQCMAAwCwYD
14
+ VR0PBAQDAgSwMB0GA1UdDgQWBBQEd3/D0MMj9FHhMZk0QJDlrUtKaTAcBgNVHREE
15
+ FTATgRFjaHJpc0BvbHN0cm9tLmNvbTAcBgNVHRIEFTATgRFjaHJpc0BvbHN0cm9t
16
+ LmNvbTANBgkqhkiG9w0BAQsFAAOCAYEALritM5RkGNZ7cs8hlljSEyuwJrbJYOSX
17
+ 6p1S0D83GlfGZ/5XABy1p4EGQjxiAYuDrnnIw6GLHpgxFEtUNvyNYVfAa6u6yz4Y
18
+ nEjbEF76zAAxoRfivDApGJ3G9wuZ14cHZswFJppf2N4RG14F8bfLtU1OMYDLw8eK
19
+ QJOpynqHtrSj+FfsyNb6d93K8rlNCEd4UHkdRH1m7VnG6M18HvkbQCRMJtOFg/3j
20
+ c66TgdClDMJJXXiktVinfsmpTwxe2IzjGvwo2CZ/S53WPU/jb4uQMUzY0tMw48rl
21
+ S07/1DQNogstTnLYueqkUS1PYEwtavKVnpAtnaOdf0rJ/Rk4hA36BRgAVyQrp0uu
22
+ mSbo3NCvepJNYsTOUM+Df421VuPq713JV0aJDqltyfPptTM7fmNMcukbRh0aRuMT
23
+ EIKh6yDoB+oCRuiTV0uw/lKE2PtbONhJb7uN1qhZqla/iBpmUjiEu8+skI+ygv9n
24
+ 7Krw8FJrV3+VRCiZTPKHeshAfL9yeIZh
25
+ -----END CERTIFICATE-----
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: invocations
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.6
5
+ platform: ruby
6
+ authors:
7
+ - Chris Olstrom
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain:
11
+ - |
12
+ -----BEGIN CERTIFICATE-----
13
+ MIIENDCCApygAwIBAgIBATANBgkqhkiG9w0BAQsFADAiMSAwHgYDVQQDDBdjaHJp
14
+ cy9EQz1vbHN0cm9tL0RDPWNvbTAeFw0xODAzMTUxODMxMTdaFw0xOTAzMTUxODMx
15
+ MTdaMCIxIDAeBgNVBAMMF2NocmlzL0RDPW9sc3Ryb20vREM9Y29tMIIBojANBgkq
16
+ hkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAp31YmQvpMuQSlgX22B++/rxl4p4LYyaq
17
+ cDDbi8DBro9cm2H60lbpCuAUALiED2CagZEK0vel5W8AnZhhns0OEYAlpQtBSJtN
18
+ 8P/jlNYruuY26aVhfHfyA5j1n7tVecJz3i/awEPGC3zuTfvUq7Ahn5czOy+hIm4M
19
+ epee881dqnJlXjzTX/TKFYQa9tYj4bhsjfJOV+EDMcao/DE3vmNcBKH8XFVv/wQe
20
+ MGC7VY5zBwow00AkCicNmIr0Psy5hLvqphJ/E3Eiu4UpXhiBfM0z7xiBPoPMBqOx
21
+ r1RzgfKm/JbDO7leFmrEi8hLofyMmbuGvrSTE274vS4EnKaW6OtK7QM5R+jOJZbd
22
+ 67KUgSw+LdHNwu8xCuuQOdKPeSfWdNz94KAdczjzHdXUl/SpfmTuN/D+BCZjTxSo
23
+ F1kACSU6uGTBFKZy35XK+yqeny/1l6xRs6j+cON+LSRMKYSt7jdLcKQVk5wH2xLo
24
+ 83njwnumFxKhiWu0oaT5dlDCtyYM85j9AgMBAAGjdTBzMAkGA1UdEwQCMAAwCwYD
25
+ VR0PBAQDAgSwMB0GA1UdDgQWBBQEd3/D0MMj9FHhMZk0QJDlrUtKaTAcBgNVHREE
26
+ FTATgRFjaHJpc0BvbHN0cm9tLmNvbTAcBgNVHRIEFTATgRFjaHJpc0BvbHN0cm9t
27
+ LmNvbTANBgkqhkiG9w0BAQsFAAOCAYEALritM5RkGNZ7cs8hlljSEyuwJrbJYOSX
28
+ 6p1S0D83GlfGZ/5XABy1p4EGQjxiAYuDrnnIw6GLHpgxFEtUNvyNYVfAa6u6yz4Y
29
+ nEjbEF76zAAxoRfivDApGJ3G9wuZ14cHZswFJppf2N4RG14F8bfLtU1OMYDLw8eK
30
+ QJOpynqHtrSj+FfsyNb6d93K8rlNCEd4UHkdRH1m7VnG6M18HvkbQCRMJtOFg/3j
31
+ c66TgdClDMJJXXiktVinfsmpTwxe2IzjGvwo2CZ/S53WPU/jb4uQMUzY0tMw48rl
32
+ S07/1DQNogstTnLYueqkUS1PYEwtavKVnpAtnaOdf0rJ/Rk4hA36BRgAVyQrp0uu
33
+ mSbo3NCvepJNYsTOUM+Df421VuPq713JV0aJDqltyfPptTM7fmNMcukbRh0aRuMT
34
+ EIKh6yDoB+oCRuiTV0uw/lKE2PtbONhJb7uN1qhZqla/iBpmUjiEu8+skI+ygv9n
35
+ 7Krw8FJrV3+VRCiZTPKHeshAfL9yeIZh
36
+ -----END CERTIFICATE-----
37
+ date: 2018-05-10 00:00:00.000000000 Z
38
+ dependencies: []
39
+ description:
40
+ email: chris@olstrom.com
41
+ executables: []
42
+ extensions: []
43
+ extra_rdoc_files: []
44
+ files:
45
+ - ".gitignore"
46
+ - Gemfile
47
+ - LICENSE.txt
48
+ - README.org
49
+ - invocations.gemspec
50
+ - lib/invocations.rb
51
+ - lib/invocations/invocation.rb
52
+ - tests/invocations.rb
53
+ - trust/certificates/colstrom.pem
54
+ homepage: https://github.com/colstrom/invocations
55
+ licenses:
56
+ - MIT
57
+ metadata: {}
58
+ post_install_message:
59
+ rdoc_options: []
60
+ require_paths:
61
+ - lib
62
+ required_ruby_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - "~>"
65
+ - !ruby/object:Gem::Version
66
+ version: 2.3.0
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ requirements: []
73
+ rubyforge_project:
74
+ rubygems_version: 2.7.6
75
+ signing_key:
76
+ specification_version: 4
77
+ summary: Drop-in alternative to procs and lambdas.
78
+ test_files: []
Binary file