invokable 0.5.1 → 0.5.2
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 +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +4 -6
- data/lib/invokable/closure.rb +116 -0
- data/lib/invokable/command.rb +3 -102
- data/lib/invokable/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b107ca53f8d89104fa38152d27141d24ae62dbec10e8e313b1428b5e711f61e9
|
4
|
+
data.tar.gz: b17e3b4207c4262637a08975772063f8d99583c6ef472220e18598885c272860
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c036b555078552a8902b83ccb7800ce878c23844a3ac6c7586d510622a56ba9ef0e4da985773662d5a605566308bb1c835b28eb988b417cc5a42a1c92aa95464
|
7
|
+
data.tar.gz: 900fab835907e7a8af2f8284629361ed0fbe1db81e6d05d8a2a98152fc223e4a44de352eb1eba538a9e53d406e95d97bcf4ad82f133a96e91c282626999175a7
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -49,14 +49,12 @@ User.all.map(&data_for_user)
|
|
49
49
|
```ruby
|
50
50
|
# command objects that enclose state, can be treated as automatically curried functions.
|
51
51
|
require 'invokable'
|
52
|
-
require 'invokable/
|
52
|
+
require 'invokable/closure'
|
53
53
|
|
54
54
|
class TwitterPoster
|
55
|
-
include Invokable::
|
55
|
+
include Invokable::Closure
|
56
56
|
|
57
|
-
enclose
|
58
|
-
@model = model
|
59
|
-
end
|
57
|
+
enclose :model
|
60
58
|
|
61
59
|
def call(user)
|
62
60
|
# do the dirt
|
@@ -77,7 +75,7 @@ Use as much or a little as you need:
|
|
77
75
|
|
78
76
|
```ruby
|
79
77
|
require 'invokable' # loads Invokable module
|
80
|
-
require 'invokable/
|
78
|
+
require 'invokable/closure' # loads Invokable::Closure module
|
81
79
|
require 'invokable/hash' # loads hash patch
|
82
80
|
require 'invokable/array' # loads array patch
|
83
81
|
require 'invokable/set' # loads set patch
|
@@ -0,0 +1,116 @@
|
|
1
|
+
module Invokable
|
2
|
+
# Treat classes 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.2
|
7
|
+
module Closure
|
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
|
+
return @initializer_arity if @initializer_arity
|
35
|
+
|
36
|
+
@initializer ? @initializer.arity : 0
|
37
|
+
end
|
38
|
+
|
39
|
+
# Handle automatic currying--will accept either the initializer arity or the total arity of the class. If
|
40
|
+
# the initializer arity is used return a class instance. If the total arity is used instantiate the class
|
41
|
+
# and return the results of the `call` method.
|
42
|
+
#
|
43
|
+
# @version 0.5.0
|
44
|
+
# @see arity
|
45
|
+
# @see initializer_arity
|
46
|
+
def call(*args)
|
47
|
+
if args.length == initializer_arity
|
48
|
+
new(*args)
|
49
|
+
elsif args.length == arity
|
50
|
+
init_args = args.slice(0, initializer_arity)
|
51
|
+
call_args = args.slice(initializer_arity, args.length)
|
52
|
+
new(*init_args).call(*call_args)
|
53
|
+
else
|
54
|
+
raise ArgumentError, "wrong number of arguments (given #{args.length}, expected #{initializer_arity} or #{arity})"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Specify any enclosed state with a block or named attributes
|
59
|
+
#
|
60
|
+
# @example
|
61
|
+
# class TwitterPater
|
62
|
+
# include Invokable::Command
|
63
|
+
#
|
64
|
+
# enclose :api_key
|
65
|
+
#
|
66
|
+
# def call(user)
|
67
|
+
# # interact with twitter, return results
|
68
|
+
# end
|
69
|
+
# end
|
70
|
+
#
|
71
|
+
# TwitterPater.new(API_KEY).call(User.find(1))
|
72
|
+
# TwitterPater.new(API_KEY).api_key == API_KEY # => true
|
73
|
+
#
|
74
|
+
# class TwitterPater
|
75
|
+
# include Invokable::Command
|
76
|
+
#
|
77
|
+
# enclose do |api_key|
|
78
|
+
# @api_key = api_key
|
79
|
+
# end
|
80
|
+
#
|
81
|
+
# def call(user)
|
82
|
+
# # interact with twitter, return results
|
83
|
+
# end
|
84
|
+
# end
|
85
|
+
#
|
86
|
+
# TwitterPater.new(API_KEY).call(User.find(1))
|
87
|
+
# TwitterPater.new(API_KEY).api_key # error 'method' missing
|
88
|
+
def enclose(*names, &block)
|
89
|
+
return define_initializer_with_block(block) unless block.nil?
|
90
|
+
|
91
|
+
define_initializer_with_names(names)
|
92
|
+
end
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
def define_initializer_with_block(block)
|
97
|
+
@initializer = block
|
98
|
+
define_method :initialize, &block
|
99
|
+
end
|
100
|
+
|
101
|
+
def define_initializer_with_names(names)
|
102
|
+
@initializer_arity = names.length
|
103
|
+
|
104
|
+
names.each do |name|
|
105
|
+
attr_reader name
|
106
|
+
end
|
107
|
+
|
108
|
+
define_method :initialize do |*args|
|
109
|
+
names.each_with_index do |name, i|
|
110
|
+
instance_variable_set(:"@#{name}", args[i])
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
data/lib/invokable/command.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require_relative 'closure'
|
2
|
+
|
1
3
|
module Invokable
|
2
4
|
# Treat "Command Objects" as curried functions
|
3
5
|
#
|
@@ -9,108 +11,7 @@ module Invokable
|
|
9
11
|
klass.include(Invokable)
|
10
12
|
klass.extend(Invokable::Core)
|
11
13
|
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
|
-
return @initializer_arity if @initializer_arity
|
35
|
-
|
36
|
-
@initializer ? @initializer.arity : 0
|
37
|
-
end
|
38
|
-
|
39
|
-
# Handle automatic currying--will accept either the initializer arity or the total arity of the class. If
|
40
|
-
# the initializer arity is used return a class instance. If the total arity is used instantiate the class
|
41
|
-
# and return the results of the `call` method.
|
42
|
-
#
|
43
|
-
# @version 0.5.0
|
44
|
-
# @see arity
|
45
|
-
# @see initializer_arity
|
46
|
-
def call(*args)
|
47
|
-
if args.length == initializer_arity
|
48
|
-
new(*args)
|
49
|
-
elsif args.length == arity
|
50
|
-
init_args = args.slice(0, initializer_arity)
|
51
|
-
call_args = args.slice(initializer_arity, args.length)
|
52
|
-
new(*init_args).call(*call_args)
|
53
|
-
else
|
54
|
-
raise ArgumentError, "wrong number of arguments (given #{args.length}, expected #{initializer_arity} or #{arity})"
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
# Specify any enclosed state with a block or named attributes
|
59
|
-
#
|
60
|
-
# @example
|
61
|
-
# class TwitterPater
|
62
|
-
# include Invokable::Command
|
63
|
-
#
|
64
|
-
# enclose :api_key
|
65
|
-
#
|
66
|
-
# def call(user)
|
67
|
-
# # interact with twitter, return results
|
68
|
-
# end
|
69
|
-
# end
|
70
|
-
#
|
71
|
-
# TwitterPater.new(API_KEY).call(User.find(1))
|
72
|
-
# TwitterPater.new(API_KEY).api_key == API_KEY # => true
|
73
|
-
#
|
74
|
-
# class TwitterPater
|
75
|
-
# include Invokable::Command
|
76
|
-
#
|
77
|
-
# enclose do |api_key|
|
78
|
-
# @api_key = api_key
|
79
|
-
# end
|
80
|
-
#
|
81
|
-
# def call(user)
|
82
|
-
# # interact with twitter, return results
|
83
|
-
# end
|
84
|
-
# end
|
85
|
-
#
|
86
|
-
# TwitterPater.new(API_KEY).call(User.find(1))
|
87
|
-
# TwitterPater.new(API_KEY).api_key # error 'method' missing
|
88
|
-
def enclose(*names, &block)
|
89
|
-
return define_initializer_with_block(block) unless block.nil?
|
90
|
-
|
91
|
-
define_initializer_with_names(names)
|
92
|
-
end
|
93
|
-
|
94
|
-
private
|
95
|
-
|
96
|
-
def define_initializer_with_block(block)
|
97
|
-
@initializer = block
|
98
|
-
define_method :initialize, &block
|
99
|
-
end
|
100
|
-
|
101
|
-
def define_initializer_with_names(names)
|
102
|
-
@initializer_arity = names.length
|
103
|
-
|
104
|
-
names.each do |name|
|
105
|
-
attr_reader name
|
106
|
-
end
|
107
|
-
|
108
|
-
define_method :initialize do |*args|
|
109
|
-
names.each_with_index do |name, i|
|
110
|
-
instance_variable_set(:"@#{name}", args[i])
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
14
|
+
klass.extend(Invokable::Closure::ClassMethods)
|
114
15
|
end
|
115
16
|
end
|
116
17
|
end
|
data/lib/invokable/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: invokable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Delon Newman
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-07-
|
11
|
+
date: 2020-07-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -72,6 +72,7 @@ files:
|
|
72
72
|
- invokable.gemspec
|
73
73
|
- lib/invokable.rb
|
74
74
|
- lib/invokable/array.rb
|
75
|
+
- lib/invokable/closure.rb
|
75
76
|
- lib/invokable/command.rb
|
76
77
|
- lib/invokable/compose.rb
|
77
78
|
- lib/invokable/core.rb
|