invocations 0.2.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -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