activefunction-core 0.2.0 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -0
- data/README.md +1 -1
- data/lib/.rbnext/2.7/{plugins → active_function_core/plugins}/hooks.rb +96 -11
- data/lib/.rbnext/3.0/{plugins → active_function_core/plugins}/hooks.rb +96 -11
- data/lib/.rbnext/3.1/{plugins → active_function_core/plugins}/hooks.rb +96 -11
- data/lib/.rbnext/3.2/{plugins → active_function_core/plugins}/hooks.rb +96 -11
- data/lib/{plugins → active_function_core/plugins}/hooks.rb +96 -11
- data/lib/active_function_core/version.rb +1 -1
- data/lib/active_function_core.rb +0 -2
- metadata +12 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a1f66462455352552a6c2746a76a215f3a497b04610d05ad43db175d2ac9b811
|
4
|
+
data.tar.gz: ce06fea28a775ef62692599895ca6e96035efa69f7ba02a0f659c7baf499ca48
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 44a481313a83af1eaf5dd6de1356f8ff7e16d7d49572a812da8eee33b76618dd2afb3811a19d35d6bb1fb75e701d41b62d4b10bc06cef79caef29e278cc4ec0c
|
7
|
+
data.tar.gz: e2a37509372b1d0762b1412eb1ad52b7ed83fa7c2d1ef410e27c308324a0d544095653934ff2c0727e4fc97dcbe7892a303483b3da134cc05cd192c6943edbb7
|
data/CHANGELOG.md
CHANGED
@@ -11,3 +11,14 @@
|
|
11
11
|
- Added Plugins support
|
12
12
|
- Added Hooks plugin - refactored ActiveFunction::Functions::Callbacks implementation.
|
13
13
|
|
14
|
+
## [0.2.1] - Yanked due to invalid .rbnext files
|
15
|
+
|
16
|
+
- Fixed Plugins options handling
|
17
|
+
|
18
|
+
## [0.2.2]
|
19
|
+
|
20
|
+
- Republish 0.2.1
|
21
|
+
|
22
|
+
## [0.2.3]
|
23
|
+
|
24
|
+
- YARD Doc Added
|
data/README.md
CHANGED
@@ -11,15 +11,60 @@ end
|
|
11
11
|
|
12
12
|
module ActiveFunctionCore
|
13
13
|
module Plugins
|
14
|
+
# Provides ActiveSupport::Callbacks like DSL for defining before and after callbacks around methods
|
15
|
+
# @see ClassMethods DSL methods.
|
16
|
+
# @example Hooks with default callback options
|
17
|
+
# class YourClass
|
18
|
+
# include ActiveFunctionCore::Plugins::Hooks
|
19
|
+
#
|
20
|
+
# define_hooks_for :your_method
|
21
|
+
#
|
22
|
+
# before_your_method :do_something_before, if: :condition_met?
|
23
|
+
# after_your_method :do_something_after, unless: :condition_met?
|
24
|
+
#
|
25
|
+
# def your_method
|
26
|
+
# # Method implementation here...
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# private
|
30
|
+
#
|
31
|
+
# def condition_met?
|
32
|
+
# # Condition logic here...
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# def do_something_before
|
36
|
+
# # Callback logic to execute before your_method
|
37
|
+
# end
|
38
|
+
#
|
39
|
+
# def do_something_after
|
40
|
+
# # Callback logic to execute after your_method
|
41
|
+
# end
|
42
|
+
# end
|
43
|
+
# @example Hooks with custom callback options
|
44
|
+
# class YourClass
|
45
|
+
# include ActiveFunction::Core::Plugins::Hooks
|
46
|
+
#
|
47
|
+
# set_callback_options only: ->(only_methods, context:) { only_methods.include?(context.action) }
|
48
|
+
#
|
49
|
+
# define_hooks_for :your_method
|
50
|
+
#
|
51
|
+
# before_your_method :do_something_before, only: %[foo bar]
|
52
|
+
#
|
53
|
+
# def action = "foo"
|
54
|
+
# end
|
14
55
|
module Hooks
|
56
|
+
# Represents a hook with callbacks for a specific method.
|
15
57
|
class Hook < Data.define(:method_name, :callbacks)
|
16
58
|
DEFAULT_CALLBACK_OPTIONS = {
|
17
59
|
if: ->(v, context:) { context.send(v) if context.respond_to?(v, true) },
|
18
60
|
unless: ->(v, context:) { !context.send(v) if context.respond_to?(v, true) }
|
19
61
|
}.freeze
|
20
62
|
SUPPORTED_CALLBACKS = %i[before after].freeze
|
21
|
-
|
22
|
-
Callback
|
63
|
+
# Represents a callback with options.
|
64
|
+
Callback = Data.define(:options, :target) do
|
65
|
+
# Runs the callback within the specified contex.
|
66
|
+
#
|
67
|
+
# @param context [Object] instance of class with callbacks.
|
23
68
|
def run(context)
|
24
69
|
raise ArgumentError, "Callback target #{target} is not defined" unless context.respond_to?(target, true)
|
25
70
|
raise ArgumentError, ":callback_options is not defined in #{context.class}" unless context.class.respond_to?(:callback_options)
|
@@ -31,7 +76,7 @@ module ActiveFunctionCore
|
|
31
76
|
|
32
77
|
private def normalized_options(options, context)
|
33
78
|
options.map do |option|
|
34
|
-
name, arg = option
|
79
|
+
name, arg = option
|
35
80
|
-> { context.class.callback_options[name].call(arg, context: context) }
|
36
81
|
end
|
37
82
|
end
|
@@ -41,6 +86,14 @@ module ActiveFunctionCore
|
|
41
86
|
super(callbacks: callbacks.to_h { |_1| [_1, []] }, **__kwrest__)
|
42
87
|
end
|
43
88
|
|
89
|
+
# Adds a callback to the hook.
|
90
|
+
#
|
91
|
+
# @param type [Symbol] the type of callback, `:before` or `:after`
|
92
|
+
# @param target [Symbol] the name of the callback method.
|
93
|
+
# @param options [Hash] the options for the callback.
|
94
|
+
# @options options [Symbol] :if the name of the method to check before executing the callback.
|
95
|
+
# @options options [Symbol] :unless the name of the method to check before executing the callback.
|
96
|
+
# @raise [ArgumentError] if callback already defined.
|
44
97
|
def add_callback(type:, target:, options: {})
|
45
98
|
callbacks[type] << Callback[options, target].tap do |callback|
|
46
99
|
next unless callbacks[type].map(&:hash).to_set === callback.hash
|
@@ -49,6 +102,11 @@ module ActiveFunctionCore
|
|
49
102
|
end
|
50
103
|
end
|
51
104
|
|
105
|
+
# Runs all callbacks for the hook.
|
106
|
+
#
|
107
|
+
# @param context [Object] instance of class with defined hook.
|
108
|
+
# @yield [*args] block of code around which callbacks will be executed.
|
109
|
+
# @return the result of the block.
|
52
110
|
def run_callbacks(context, &block)
|
53
111
|
callbacks[:before].each { |it| it.run(context) }
|
54
112
|
|
@@ -60,24 +118,33 @@ module ActiveFunctionCore
|
|
60
118
|
end
|
61
119
|
end
|
62
120
|
|
63
|
-
|
64
|
-
base.extend(ClassMethods)
|
65
|
-
end
|
66
|
-
|
121
|
+
# DSL method for {ActiveFunctionCore::Plugins::Hooks}
|
67
122
|
module ClassMethods
|
123
|
+
# Returns all setuped hooks for the class.
|
68
124
|
def hooks ; @__hooks ||= {}; end
|
125
|
+
|
126
|
+
# Returns all setuped custom callback options for the class.
|
69
127
|
def callback_options ; @__callback_options ||= Hook::DEFAULT_CALLBACK_OPTIONS.dup; end
|
70
128
|
|
129
|
+
# Inherited callback to ensure that callbacks are inherited from the base class.
|
71
130
|
def inherited(subclass)
|
72
131
|
subclass.instance_variable_set(:@__hooks, Marshal.load(Marshal.dump(hooks)))
|
73
132
|
subclass.instance_variable_set(:@__callback_options, callback_options.dup)
|
74
133
|
end
|
75
134
|
|
135
|
+
# Setups hooks for provided method.
|
76
136
|
# Redefines method providing callbacks calls around it.
|
77
|
-
# Defines
|
137
|
+
# Defines *before_[name]* and *after_[name]* methods for setting callbacks.
|
138
|
+
#
|
139
|
+
# @example
|
140
|
+
# define_hooks_for :process, name: :action
|
141
|
+
# before_action :set_first
|
142
|
+
# after_action :set_last, if: :ok?
|
78
143
|
#
|
79
144
|
# @param method [Symbol] the name of the callbackable method.
|
80
145
|
# @param name [Symbol] alias for hooked method before_[name] & after_[name] methods.
|
146
|
+
# @raise [ArgumentError] if hook for method already defined.
|
147
|
+
# @raise [ArgumentError] if method is not defined.
|
81
148
|
def define_hooks_for(method, name: method)
|
82
149
|
raise(ArgumentError, "Hook for #{method} are already defined") if hooks.key?(method)
|
83
150
|
raise(ArgumentError, "Method #{method} is not defined") unless method_defined?(method)
|
@@ -101,21 +168,35 @@ module ActiveFunctionCore
|
|
101
168
|
|
102
169
|
# Sets a callback for an existing hook'ed method.
|
103
170
|
#
|
171
|
+
# @example
|
172
|
+
# define_hooks_for :action
|
173
|
+
# set_callback :before, :action, :set_first
|
174
|
+
#
|
104
175
|
# @param type [Symbol] the type of callback, `:before` or `:after`
|
105
176
|
# @param method_name [Symbol] the name of the callbackable method.
|
106
177
|
# @param target [Symbol] the name of the callback method.
|
107
178
|
# @param options [Hash] the options for the callback.
|
108
|
-
# @
|
179
|
+
# @option options [Symbol] :if the name of the booled method to call before executing the callback.
|
180
|
+
# @option options [Symbol] :unless the name of the booled method to call before executing the callback.
|
181
|
+
# @raise [ArgumentError] if hook for provided method is not setuped via ::define_hooks_for.
|
182
|
+
# @raise [ArgumentError] if unsupported @options was passed.
|
109
183
|
def set_callback(type, method_name, target, options = {})
|
110
184
|
raise(ArgumentError, "Hook for :#{method_name} is not defined") unless hooks.key?(method_name)
|
111
|
-
raise(ArgumentError, "Hook Callback accepts only #{
|
185
|
+
raise(ArgumentError, "Hook Callback accepts only #{callback_options.keys} options") if (options.keys - callback_options.keys).any?
|
112
186
|
|
113
187
|
hooks[method_name].add_callback(type: type, target: target, options: options)
|
114
188
|
end
|
115
189
|
|
116
190
|
# Sets a custom callback option.
|
117
191
|
#
|
118
|
-
# @
|
192
|
+
# @example
|
193
|
+
# set_callback_option only: ->(args, context:) { args.to_set === context.current_action }
|
194
|
+
# define_hooks_for :action
|
195
|
+
# before_action :set_first, only: :index
|
196
|
+
#
|
197
|
+
# @param option [Hash{Symbol => Proc}] The custom callback option as a single-value hash.
|
198
|
+
# - :name [Symbol] The name of the option.
|
199
|
+
# - :block [Proc] The block to call.
|
119
200
|
# @yield [*attrs, context:] the block to call.
|
120
201
|
# @yieldparam attrs [*] the attributes passed to the option.
|
121
202
|
# @yieldparam context [Object] the instance context (optional).
|
@@ -125,6 +206,10 @@ module ActiveFunctionCore
|
|
125
206
|
callback_options[name] = block
|
126
207
|
end
|
127
208
|
end
|
209
|
+
|
210
|
+
def self.included(base)
|
211
|
+
base.extend(ClassMethods)
|
212
|
+
end
|
128
213
|
end
|
129
214
|
end
|
130
215
|
end
|
@@ -11,15 +11,60 @@ end
|
|
11
11
|
|
12
12
|
module ActiveFunctionCore
|
13
13
|
module Plugins
|
14
|
+
# Provides ActiveSupport::Callbacks like DSL for defining before and after callbacks around methods
|
15
|
+
# @see ClassMethods DSL methods.
|
16
|
+
# @example Hooks with default callback options
|
17
|
+
# class YourClass
|
18
|
+
# include ActiveFunctionCore::Plugins::Hooks
|
19
|
+
#
|
20
|
+
# define_hooks_for :your_method
|
21
|
+
#
|
22
|
+
# before_your_method :do_something_before, if: :condition_met?
|
23
|
+
# after_your_method :do_something_after, unless: :condition_met?
|
24
|
+
#
|
25
|
+
# def your_method
|
26
|
+
# # Method implementation here...
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# private
|
30
|
+
#
|
31
|
+
# def condition_met?
|
32
|
+
# # Condition logic here...
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# def do_something_before
|
36
|
+
# # Callback logic to execute before your_method
|
37
|
+
# end
|
38
|
+
#
|
39
|
+
# def do_something_after
|
40
|
+
# # Callback logic to execute after your_method
|
41
|
+
# end
|
42
|
+
# end
|
43
|
+
# @example Hooks with custom callback options
|
44
|
+
# class YourClass
|
45
|
+
# include ActiveFunction::Core::Plugins::Hooks
|
46
|
+
#
|
47
|
+
# set_callback_options only: ->(only_methods, context:) { only_methods.include?(context.action) }
|
48
|
+
#
|
49
|
+
# define_hooks_for :your_method
|
50
|
+
#
|
51
|
+
# before_your_method :do_something_before, only: %[foo bar]
|
52
|
+
#
|
53
|
+
# def action = "foo"
|
54
|
+
# end
|
14
55
|
module Hooks
|
56
|
+
# Represents a hook with callbacks for a specific method.
|
15
57
|
class Hook < Data.define(:method_name, :callbacks)
|
16
58
|
DEFAULT_CALLBACK_OPTIONS = {
|
17
59
|
if: ->(v, context:) { context.send(v) if context.respond_to?(v, true) },
|
18
60
|
unless: ->(v, context:) { !context.send(v) if context.respond_to?(v, true) }
|
19
61
|
}.freeze
|
20
62
|
SUPPORTED_CALLBACKS = %i[before after].freeze
|
21
|
-
|
22
|
-
Callback
|
63
|
+
# Represents a callback with options.
|
64
|
+
Callback = Data.define(:options, :target) do
|
65
|
+
# Runs the callback within the specified contex.
|
66
|
+
#
|
67
|
+
# @param context [Object] instance of class with callbacks.
|
23
68
|
def run(context)
|
24
69
|
raise ArgumentError, "Callback target #{target} is not defined" unless context.respond_to?(target, true)
|
25
70
|
raise ArgumentError, ":callback_options is not defined in #{context.class}" unless context.class.respond_to?(:callback_options)
|
@@ -31,7 +76,7 @@ module ActiveFunctionCore
|
|
31
76
|
|
32
77
|
private def normalized_options(options, context)
|
33
78
|
options.map do |option|
|
34
|
-
name, arg = option
|
79
|
+
name, arg = option
|
35
80
|
-> { context.class.callback_options[name].call(arg, context: context) }
|
36
81
|
end
|
37
82
|
end
|
@@ -41,6 +86,14 @@ module ActiveFunctionCore
|
|
41
86
|
super(callbacks: callbacks.to_h { [_1, []] }, **__kwrest__)
|
42
87
|
end
|
43
88
|
|
89
|
+
# Adds a callback to the hook.
|
90
|
+
#
|
91
|
+
# @param type [Symbol] the type of callback, `:before` or `:after`
|
92
|
+
# @param target [Symbol] the name of the callback method.
|
93
|
+
# @param options [Hash] the options for the callback.
|
94
|
+
# @options options [Symbol] :if the name of the method to check before executing the callback.
|
95
|
+
# @options options [Symbol] :unless the name of the method to check before executing the callback.
|
96
|
+
# @raise [ArgumentError] if callback already defined.
|
44
97
|
def add_callback(type:, target:, options: {})
|
45
98
|
callbacks[type] << Callback[options, target].tap do |callback|
|
46
99
|
next unless callbacks[type].map(&:hash).to_set === callback.hash
|
@@ -49,6 +102,11 @@ module ActiveFunctionCore
|
|
49
102
|
end
|
50
103
|
end
|
51
104
|
|
105
|
+
# Runs all callbacks for the hook.
|
106
|
+
#
|
107
|
+
# @param context [Object] instance of class with defined hook.
|
108
|
+
# @yield [*args] block of code around which callbacks will be executed.
|
109
|
+
# @return the result of the block.
|
52
110
|
def run_callbacks(context, &block)
|
53
111
|
callbacks[:before].each { |it| it.run(context) }
|
54
112
|
|
@@ -60,24 +118,33 @@ module ActiveFunctionCore
|
|
60
118
|
end
|
61
119
|
end
|
62
120
|
|
63
|
-
|
64
|
-
base.extend(ClassMethods)
|
65
|
-
end
|
66
|
-
|
121
|
+
# DSL method for {ActiveFunctionCore::Plugins::Hooks}
|
67
122
|
module ClassMethods
|
123
|
+
# Returns all setuped hooks for the class.
|
68
124
|
def hooks ; @__hooks ||= {}; end
|
125
|
+
|
126
|
+
# Returns all setuped custom callback options for the class.
|
69
127
|
def callback_options ; @__callback_options ||= Hook::DEFAULT_CALLBACK_OPTIONS.dup; end
|
70
128
|
|
129
|
+
# Inherited callback to ensure that callbacks are inherited from the base class.
|
71
130
|
def inherited(subclass)
|
72
131
|
subclass.instance_variable_set(:@__hooks, Marshal.load(Marshal.dump(hooks)))
|
73
132
|
subclass.instance_variable_set(:@__callback_options, callback_options.dup)
|
74
133
|
end
|
75
134
|
|
135
|
+
# Setups hooks for provided method.
|
76
136
|
# Redefines method providing callbacks calls around it.
|
77
|
-
# Defines
|
137
|
+
# Defines *before_[name]* and *after_[name]* methods for setting callbacks.
|
138
|
+
#
|
139
|
+
# @example
|
140
|
+
# define_hooks_for :process, name: :action
|
141
|
+
# before_action :set_first
|
142
|
+
# after_action :set_last, if: :ok?
|
78
143
|
#
|
79
144
|
# @param method [Symbol] the name of the callbackable method.
|
80
145
|
# @param name [Symbol] alias for hooked method before_[name] & after_[name] methods.
|
146
|
+
# @raise [ArgumentError] if hook for method already defined.
|
147
|
+
# @raise [ArgumentError] if method is not defined.
|
81
148
|
def define_hooks_for(method, name: method)
|
82
149
|
raise(ArgumentError, "Hook for #{method} are already defined") if hooks.key?(method)
|
83
150
|
raise(ArgumentError, "Method #{method} is not defined") unless method_defined?(method)
|
@@ -101,21 +168,35 @@ module ActiveFunctionCore
|
|
101
168
|
|
102
169
|
# Sets a callback for an existing hook'ed method.
|
103
170
|
#
|
171
|
+
# @example
|
172
|
+
# define_hooks_for :action
|
173
|
+
# set_callback :before, :action, :set_first
|
174
|
+
#
|
104
175
|
# @param type [Symbol] the type of callback, `:before` or `:after`
|
105
176
|
# @param method_name [Symbol] the name of the callbackable method.
|
106
177
|
# @param target [Symbol] the name of the callback method.
|
107
178
|
# @param options [Hash] the options for the callback.
|
108
|
-
# @
|
179
|
+
# @option options [Symbol] :if the name of the booled method to call before executing the callback.
|
180
|
+
# @option options [Symbol] :unless the name of the booled method to call before executing the callback.
|
181
|
+
# @raise [ArgumentError] if hook for provided method is not setuped via ::define_hooks_for.
|
182
|
+
# @raise [ArgumentError] if unsupported @options was passed.
|
109
183
|
def set_callback(type, method_name, target, options = {})
|
110
184
|
raise(ArgumentError, "Hook for :#{method_name} is not defined") unless hooks.key?(method_name)
|
111
|
-
raise(ArgumentError, "Hook Callback accepts only #{
|
185
|
+
raise(ArgumentError, "Hook Callback accepts only #{callback_options.keys} options") if (options.keys - callback_options.keys).any?
|
112
186
|
|
113
187
|
hooks[method_name].add_callback(type: type, target: target, options: options)
|
114
188
|
end
|
115
189
|
|
116
190
|
# Sets a custom callback option.
|
117
191
|
#
|
118
|
-
# @
|
192
|
+
# @example
|
193
|
+
# set_callback_option only: ->(args, context:) { args.to_set === context.current_action }
|
194
|
+
# define_hooks_for :action
|
195
|
+
# before_action :set_first, only: :index
|
196
|
+
#
|
197
|
+
# @param option [Hash{Symbol => Proc}] The custom callback option as a single-value hash.
|
198
|
+
# - :name [Symbol] The name of the option.
|
199
|
+
# - :block [Proc] The block to call.
|
119
200
|
# @yield [*attrs, context:] the block to call.
|
120
201
|
# @yieldparam attrs [*] the attributes passed to the option.
|
121
202
|
# @yieldparam context [Object] the instance context (optional).
|
@@ -125,6 +206,10 @@ module ActiveFunctionCore
|
|
125
206
|
callback_options[name] = block
|
126
207
|
end
|
127
208
|
end
|
209
|
+
|
210
|
+
def self.included(base)
|
211
|
+
base.extend(ClassMethods)
|
212
|
+
end
|
128
213
|
end
|
129
214
|
end
|
130
215
|
end
|
@@ -11,15 +11,60 @@ end
|
|
11
11
|
|
12
12
|
module ActiveFunctionCore
|
13
13
|
module Plugins
|
14
|
+
# Provides ActiveSupport::Callbacks like DSL for defining before and after callbacks around methods
|
15
|
+
# @see ClassMethods DSL methods.
|
16
|
+
# @example Hooks with default callback options
|
17
|
+
# class YourClass
|
18
|
+
# include ActiveFunctionCore::Plugins::Hooks
|
19
|
+
#
|
20
|
+
# define_hooks_for :your_method
|
21
|
+
#
|
22
|
+
# before_your_method :do_something_before, if: :condition_met?
|
23
|
+
# after_your_method :do_something_after, unless: :condition_met?
|
24
|
+
#
|
25
|
+
# def your_method
|
26
|
+
# # Method implementation here...
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# private
|
30
|
+
#
|
31
|
+
# def condition_met?
|
32
|
+
# # Condition logic here...
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# def do_something_before
|
36
|
+
# # Callback logic to execute before your_method
|
37
|
+
# end
|
38
|
+
#
|
39
|
+
# def do_something_after
|
40
|
+
# # Callback logic to execute after your_method
|
41
|
+
# end
|
42
|
+
# end
|
43
|
+
# @example Hooks with custom callback options
|
44
|
+
# class YourClass
|
45
|
+
# include ActiveFunction::Core::Plugins::Hooks
|
46
|
+
#
|
47
|
+
# set_callback_options only: ->(only_methods, context:) { only_methods.include?(context.action) }
|
48
|
+
#
|
49
|
+
# define_hooks_for :your_method
|
50
|
+
#
|
51
|
+
# before_your_method :do_something_before, only: %[foo bar]
|
52
|
+
#
|
53
|
+
# def action = "foo"
|
54
|
+
# end
|
14
55
|
module Hooks
|
56
|
+
# Represents a hook with callbacks for a specific method.
|
15
57
|
class Hook < Data.define(:method_name, :callbacks)
|
16
58
|
DEFAULT_CALLBACK_OPTIONS = {
|
17
59
|
if: ->(v, context:) { context.send(v) if context.respond_to?(v, true) },
|
18
60
|
unless: ->(v, context:) { !context.send(v) if context.respond_to?(v, true) }
|
19
61
|
}.freeze
|
20
62
|
SUPPORTED_CALLBACKS = %i[before after].freeze
|
21
|
-
|
22
|
-
Callback
|
63
|
+
# Represents a callback with options.
|
64
|
+
Callback = Data.define(:options, :target) do
|
65
|
+
# Runs the callback within the specified contex.
|
66
|
+
#
|
67
|
+
# @param context [Object] instance of class with callbacks.
|
23
68
|
def run(context)
|
24
69
|
raise ArgumentError, "Callback target #{target} is not defined" unless context.respond_to?(target, true)
|
25
70
|
raise ArgumentError, ":callback_options is not defined in #{context.class}" unless context.class.respond_to?(:callback_options)
|
@@ -31,7 +76,7 @@ module ActiveFunctionCore
|
|
31
76
|
|
32
77
|
private def normalized_options(options, context)
|
33
78
|
options.map do |option|
|
34
|
-
name, arg = option
|
79
|
+
name, arg = option
|
35
80
|
-> { context.class.callback_options[name].call(arg, context: context) }
|
36
81
|
end
|
37
82
|
end
|
@@ -41,6 +86,14 @@ module ActiveFunctionCore
|
|
41
86
|
super(callbacks: callbacks.to_h { [_1, []] }, **__kwrest__)
|
42
87
|
end
|
43
88
|
|
89
|
+
# Adds a callback to the hook.
|
90
|
+
#
|
91
|
+
# @param type [Symbol] the type of callback, `:before` or `:after`
|
92
|
+
# @param target [Symbol] the name of the callback method.
|
93
|
+
# @param options [Hash] the options for the callback.
|
94
|
+
# @options options [Symbol] :if the name of the method to check before executing the callback.
|
95
|
+
# @options options [Symbol] :unless the name of the method to check before executing the callback.
|
96
|
+
# @raise [ArgumentError] if callback already defined.
|
44
97
|
def add_callback(type:, target:, options: {})
|
45
98
|
callbacks[type] << Callback[options, target].tap do |callback|
|
46
99
|
next unless callbacks[type].map(&:hash).to_set === callback.hash
|
@@ -49,6 +102,11 @@ module ActiveFunctionCore
|
|
49
102
|
end
|
50
103
|
end
|
51
104
|
|
105
|
+
# Runs all callbacks for the hook.
|
106
|
+
#
|
107
|
+
# @param context [Object] instance of class with defined hook.
|
108
|
+
# @yield [*args] block of code around which callbacks will be executed.
|
109
|
+
# @return the result of the block.
|
52
110
|
def run_callbacks(context, &block)
|
53
111
|
callbacks[:before].each { |it| it.run(context) }
|
54
112
|
|
@@ -60,24 +118,33 @@ module ActiveFunctionCore
|
|
60
118
|
end
|
61
119
|
end
|
62
120
|
|
63
|
-
|
64
|
-
base.extend(ClassMethods)
|
65
|
-
end
|
66
|
-
|
121
|
+
# DSL method for {ActiveFunctionCore::Plugins::Hooks}
|
67
122
|
module ClassMethods
|
123
|
+
# Returns all setuped hooks for the class.
|
68
124
|
def hooks = @__hooks ||= {}
|
125
|
+
|
126
|
+
# Returns all setuped custom callback options for the class.
|
69
127
|
def callback_options = @__callback_options ||= Hook::DEFAULT_CALLBACK_OPTIONS.dup
|
70
128
|
|
129
|
+
# Inherited callback to ensure that callbacks are inherited from the base class.
|
71
130
|
def inherited(subclass)
|
72
131
|
subclass.instance_variable_set(:@__hooks, Marshal.load(Marshal.dump(hooks)))
|
73
132
|
subclass.instance_variable_set(:@__callback_options, callback_options.dup)
|
74
133
|
end
|
75
134
|
|
135
|
+
# Setups hooks for provided method.
|
76
136
|
# Redefines method providing callbacks calls around it.
|
77
|
-
# Defines
|
137
|
+
# Defines *before_[name]* and *after_[name]* methods for setting callbacks.
|
138
|
+
#
|
139
|
+
# @example
|
140
|
+
# define_hooks_for :process, name: :action
|
141
|
+
# before_action :set_first
|
142
|
+
# after_action :set_last, if: :ok?
|
78
143
|
#
|
79
144
|
# @param method [Symbol] the name of the callbackable method.
|
80
145
|
# @param name [Symbol] alias for hooked method before_[name] & after_[name] methods.
|
146
|
+
# @raise [ArgumentError] if hook for method already defined.
|
147
|
+
# @raise [ArgumentError] if method is not defined.
|
81
148
|
def define_hooks_for(method, name: method)
|
82
149
|
raise(ArgumentError, "Hook for #{method} are already defined") if hooks.key?(method)
|
83
150
|
raise(ArgumentError, "Method #{method} is not defined") unless method_defined?(method)
|
@@ -101,21 +168,35 @@ module ActiveFunctionCore
|
|
101
168
|
|
102
169
|
# Sets a callback for an existing hook'ed method.
|
103
170
|
#
|
171
|
+
# @example
|
172
|
+
# define_hooks_for :action
|
173
|
+
# set_callback :before, :action, :set_first
|
174
|
+
#
|
104
175
|
# @param type [Symbol] the type of callback, `:before` or `:after`
|
105
176
|
# @param method_name [Symbol] the name of the callbackable method.
|
106
177
|
# @param target [Symbol] the name of the callback method.
|
107
178
|
# @param options [Hash] the options for the callback.
|
108
|
-
# @
|
179
|
+
# @option options [Symbol] :if the name of the booled method to call before executing the callback.
|
180
|
+
# @option options [Symbol] :unless the name of the booled method to call before executing the callback.
|
181
|
+
# @raise [ArgumentError] if hook for provided method is not setuped via ::define_hooks_for.
|
182
|
+
# @raise [ArgumentError] if unsupported @options was passed.
|
109
183
|
def set_callback(type, method_name, target, options = {})
|
110
184
|
raise(ArgumentError, "Hook for :#{method_name} is not defined") unless hooks.key?(method_name)
|
111
|
-
raise(ArgumentError, "Hook Callback accepts only #{
|
185
|
+
raise(ArgumentError, "Hook Callback accepts only #{callback_options.keys} options") if (options.keys - callback_options.keys).any?
|
112
186
|
|
113
187
|
hooks[method_name].add_callback(type: type, target: target, options: options)
|
114
188
|
end
|
115
189
|
|
116
190
|
# Sets a custom callback option.
|
117
191
|
#
|
118
|
-
# @
|
192
|
+
# @example
|
193
|
+
# set_callback_option only: ->(args, context:) { args.to_set === context.current_action }
|
194
|
+
# define_hooks_for :action
|
195
|
+
# before_action :set_first, only: :index
|
196
|
+
#
|
197
|
+
# @param option [Hash{Symbol => Proc}] The custom callback option as a single-value hash.
|
198
|
+
# - :name [Symbol] The name of the option.
|
199
|
+
# - :block [Proc] The block to call.
|
119
200
|
# @yield [*attrs, context:] the block to call.
|
120
201
|
# @yieldparam attrs [*] the attributes passed to the option.
|
121
202
|
# @yieldparam context [Object] the instance context (optional).
|
@@ -125,6 +206,10 @@ module ActiveFunctionCore
|
|
125
206
|
callback_options[name] = block
|
126
207
|
end
|
127
208
|
end
|
209
|
+
|
210
|
+
def self.included(base)
|
211
|
+
base.extend(ClassMethods)
|
212
|
+
end
|
128
213
|
end
|
129
214
|
end
|
130
215
|
end
|
@@ -11,15 +11,60 @@ end
|
|
11
11
|
|
12
12
|
module ActiveFunctionCore
|
13
13
|
module Plugins
|
14
|
+
# Provides ActiveSupport::Callbacks like DSL for defining before and after callbacks around methods
|
15
|
+
# @see ClassMethods DSL methods.
|
16
|
+
# @example Hooks with default callback options
|
17
|
+
# class YourClass
|
18
|
+
# include ActiveFunctionCore::Plugins::Hooks
|
19
|
+
#
|
20
|
+
# define_hooks_for :your_method
|
21
|
+
#
|
22
|
+
# before_your_method :do_something_before, if: :condition_met?
|
23
|
+
# after_your_method :do_something_after, unless: :condition_met?
|
24
|
+
#
|
25
|
+
# def your_method
|
26
|
+
# # Method implementation here...
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# private
|
30
|
+
#
|
31
|
+
# def condition_met?
|
32
|
+
# # Condition logic here...
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# def do_something_before
|
36
|
+
# # Callback logic to execute before your_method
|
37
|
+
# end
|
38
|
+
#
|
39
|
+
# def do_something_after
|
40
|
+
# # Callback logic to execute after your_method
|
41
|
+
# end
|
42
|
+
# end
|
43
|
+
# @example Hooks with custom callback options
|
44
|
+
# class YourClass
|
45
|
+
# include ActiveFunction::Core::Plugins::Hooks
|
46
|
+
#
|
47
|
+
# set_callback_options only: ->(only_methods, context:) { only_methods.include?(context.action) }
|
48
|
+
#
|
49
|
+
# define_hooks_for :your_method
|
50
|
+
#
|
51
|
+
# before_your_method :do_something_before, only: %[foo bar]
|
52
|
+
#
|
53
|
+
# def action = "foo"
|
54
|
+
# end
|
14
55
|
module Hooks
|
56
|
+
# Represents a hook with callbacks for a specific method.
|
15
57
|
class Hook < Data.define(:method_name, :callbacks)
|
16
58
|
DEFAULT_CALLBACK_OPTIONS = {
|
17
59
|
if: ->(v, context:) { context.send(v) if context.respond_to?(v, true) },
|
18
60
|
unless: ->(v, context:) { !context.send(v) if context.respond_to?(v, true) }
|
19
61
|
}.freeze
|
20
62
|
SUPPORTED_CALLBACKS = %i[before after].freeze
|
21
|
-
|
22
|
-
Callback
|
63
|
+
# Represents a callback with options.
|
64
|
+
Callback = Data.define(:options, :target) do
|
65
|
+
# Runs the callback within the specified contex.
|
66
|
+
#
|
67
|
+
# @param context [Object] instance of class with callbacks.
|
23
68
|
def run(context)
|
24
69
|
raise ArgumentError, "Callback target #{target} is not defined" unless context.respond_to?(target, true)
|
25
70
|
raise ArgumentError, ":callback_options is not defined in #{context.class}" unless context.class.respond_to?(:callback_options)
|
@@ -31,7 +76,7 @@ module ActiveFunctionCore
|
|
31
76
|
|
32
77
|
private def normalized_options(options, context)
|
33
78
|
options.map do |option|
|
34
|
-
name, arg = option
|
79
|
+
name, arg = option
|
35
80
|
-> { context.class.callback_options[name].call(arg, context:) }
|
36
81
|
end
|
37
82
|
end
|
@@ -41,6 +86,14 @@ module ActiveFunctionCore
|
|
41
86
|
super(callbacks: callbacks.to_h { [_1, []] }, **__kwrest__)
|
42
87
|
end
|
43
88
|
|
89
|
+
# Adds a callback to the hook.
|
90
|
+
#
|
91
|
+
# @param type [Symbol] the type of callback, `:before` or `:after`
|
92
|
+
# @param target [Symbol] the name of the callback method.
|
93
|
+
# @param options [Hash] the options for the callback.
|
94
|
+
# @options options [Symbol] :if the name of the method to check before executing the callback.
|
95
|
+
# @options options [Symbol] :unless the name of the method to check before executing the callback.
|
96
|
+
# @raise [ArgumentError] if callback already defined.
|
44
97
|
def add_callback(type:, target:, options: {})
|
45
98
|
callbacks[type] << Callback[options, target].tap do |callback|
|
46
99
|
next unless callbacks[type].map(&:hash).to_set === callback.hash
|
@@ -49,6 +102,11 @@ module ActiveFunctionCore
|
|
49
102
|
end
|
50
103
|
end
|
51
104
|
|
105
|
+
# Runs all callbacks for the hook.
|
106
|
+
#
|
107
|
+
# @param context [Object] instance of class with defined hook.
|
108
|
+
# @yield [*args] block of code around which callbacks will be executed.
|
109
|
+
# @return the result of the block.
|
52
110
|
def run_callbacks(context, &block)
|
53
111
|
callbacks[:before].each { |it| it.run(context) }
|
54
112
|
|
@@ -60,24 +118,33 @@ module ActiveFunctionCore
|
|
60
118
|
end
|
61
119
|
end
|
62
120
|
|
63
|
-
|
64
|
-
base.extend(ClassMethods)
|
65
|
-
end
|
66
|
-
|
121
|
+
# DSL method for {ActiveFunctionCore::Plugins::Hooks}
|
67
122
|
module ClassMethods
|
123
|
+
# Returns all setuped hooks for the class.
|
68
124
|
def hooks = @__hooks ||= {}
|
125
|
+
|
126
|
+
# Returns all setuped custom callback options for the class.
|
69
127
|
def callback_options = @__callback_options ||= Hook::DEFAULT_CALLBACK_OPTIONS.dup
|
70
128
|
|
129
|
+
# Inherited callback to ensure that callbacks are inherited from the base class.
|
71
130
|
def inherited(subclass)
|
72
131
|
subclass.instance_variable_set(:@__hooks, Marshal.load(Marshal.dump(hooks)))
|
73
132
|
subclass.instance_variable_set(:@__callback_options, callback_options.dup)
|
74
133
|
end
|
75
134
|
|
135
|
+
# Setups hooks for provided method.
|
76
136
|
# Redefines method providing callbacks calls around it.
|
77
|
-
# Defines
|
137
|
+
# Defines *before_[name]* and *after_[name]* methods for setting callbacks.
|
138
|
+
#
|
139
|
+
# @example
|
140
|
+
# define_hooks_for :process, name: :action
|
141
|
+
# before_action :set_first
|
142
|
+
# after_action :set_last, if: :ok?
|
78
143
|
#
|
79
144
|
# @param method [Symbol] the name of the callbackable method.
|
80
145
|
# @param name [Symbol] alias for hooked method before_[name] & after_[name] methods.
|
146
|
+
# @raise [ArgumentError] if hook for method already defined.
|
147
|
+
# @raise [ArgumentError] if method is not defined.
|
81
148
|
def define_hooks_for(method, name: method)
|
82
149
|
raise(ArgumentError, "Hook for #{method} are already defined") if hooks.key?(method)
|
83
150
|
raise(ArgumentError, "Method #{method} is not defined") unless method_defined?(method)
|
@@ -101,21 +168,35 @@ module ActiveFunctionCore
|
|
101
168
|
|
102
169
|
# Sets a callback for an existing hook'ed method.
|
103
170
|
#
|
171
|
+
# @example
|
172
|
+
# define_hooks_for :action
|
173
|
+
# set_callback :before, :action, :set_first
|
174
|
+
#
|
104
175
|
# @param type [Symbol] the type of callback, `:before` or `:after`
|
105
176
|
# @param method_name [Symbol] the name of the callbackable method.
|
106
177
|
# @param target [Symbol] the name of the callback method.
|
107
178
|
# @param options [Hash] the options for the callback.
|
108
|
-
# @
|
179
|
+
# @option options [Symbol] :if the name of the booled method to call before executing the callback.
|
180
|
+
# @option options [Symbol] :unless the name of the booled method to call before executing the callback.
|
181
|
+
# @raise [ArgumentError] if hook for provided method is not setuped via ::define_hooks_for.
|
182
|
+
# @raise [ArgumentError] if unsupported @options was passed.
|
109
183
|
def set_callback(type, method_name, target, options = {})
|
110
184
|
raise(ArgumentError, "Hook for :#{method_name} is not defined") unless hooks.key?(method_name)
|
111
|
-
raise(ArgumentError, "Hook Callback accepts only #{
|
185
|
+
raise(ArgumentError, "Hook Callback accepts only #{callback_options.keys} options") if (options.keys - callback_options.keys).any?
|
112
186
|
|
113
187
|
hooks[method_name].add_callback(type:, target:, options:)
|
114
188
|
end
|
115
189
|
|
116
190
|
# Sets a custom callback option.
|
117
191
|
#
|
118
|
-
# @
|
192
|
+
# @example
|
193
|
+
# set_callback_option only: ->(args, context:) { args.to_set === context.current_action }
|
194
|
+
# define_hooks_for :action
|
195
|
+
# before_action :set_first, only: :index
|
196
|
+
#
|
197
|
+
# @param option [Hash{Symbol => Proc}] The custom callback option as a single-value hash.
|
198
|
+
# - :name [Symbol] The name of the option.
|
199
|
+
# - :block [Proc] The block to call.
|
119
200
|
# @yield [*attrs, context:] the block to call.
|
120
201
|
# @yieldparam attrs [*] the attributes passed to the option.
|
121
202
|
# @yieldparam context [Object] the instance context (optional).
|
@@ -125,6 +206,10 @@ module ActiveFunctionCore
|
|
125
206
|
callback_options[name] = block
|
126
207
|
end
|
127
208
|
end
|
209
|
+
|
210
|
+
def self.included(base)
|
211
|
+
base.extend(ClassMethods)
|
212
|
+
end
|
128
213
|
end
|
129
214
|
end
|
130
215
|
end
|
@@ -11,15 +11,60 @@ end
|
|
11
11
|
|
12
12
|
module ActiveFunctionCore
|
13
13
|
module Plugins
|
14
|
+
# Provides ActiveSupport::Callbacks like DSL for defining before and after callbacks around methods
|
15
|
+
# @see ClassMethods DSL methods.
|
16
|
+
# @example Hooks with default callback options
|
17
|
+
# class YourClass
|
18
|
+
# include ActiveFunctionCore::Plugins::Hooks
|
19
|
+
#
|
20
|
+
# define_hooks_for :your_method
|
21
|
+
#
|
22
|
+
# before_your_method :do_something_before, if: :condition_met?
|
23
|
+
# after_your_method :do_something_after, unless: :condition_met?
|
24
|
+
#
|
25
|
+
# def your_method
|
26
|
+
# # Method implementation here...
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# private
|
30
|
+
#
|
31
|
+
# def condition_met?
|
32
|
+
# # Condition logic here...
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# def do_something_before
|
36
|
+
# # Callback logic to execute before your_method
|
37
|
+
# end
|
38
|
+
#
|
39
|
+
# def do_something_after
|
40
|
+
# # Callback logic to execute after your_method
|
41
|
+
# end
|
42
|
+
# end
|
43
|
+
# @example Hooks with custom callback options
|
44
|
+
# class YourClass
|
45
|
+
# include ActiveFunction::Core::Plugins::Hooks
|
46
|
+
#
|
47
|
+
# set_callback_options only: ->(only_methods, context:) { only_methods.include?(context.action) }
|
48
|
+
#
|
49
|
+
# define_hooks_for :your_method
|
50
|
+
#
|
51
|
+
# before_your_method :do_something_before, only: %[foo bar]
|
52
|
+
#
|
53
|
+
# def action = "foo"
|
54
|
+
# end
|
14
55
|
module Hooks
|
56
|
+
# Represents a hook with callbacks for a specific method.
|
15
57
|
class Hook < Data.define(:method_name, :callbacks)
|
16
58
|
DEFAULT_CALLBACK_OPTIONS = {
|
17
59
|
if: ->(v, context:) { context.send(v) if context.respond_to?(v, true) },
|
18
60
|
unless: ->(v, context:) { !context.send(v) if context.respond_to?(v, true) }
|
19
61
|
}.freeze
|
20
62
|
SUPPORTED_CALLBACKS = %i[before after].freeze
|
21
|
-
|
22
|
-
Callback
|
63
|
+
# Represents a callback with options.
|
64
|
+
Callback = Data.define(:options, :target) do
|
65
|
+
# Runs the callback within the specified contex.
|
66
|
+
#
|
67
|
+
# @param context [Object] instance of class with callbacks.
|
23
68
|
def run(context)
|
24
69
|
raise ArgumentError, "Callback target #{target} is not defined" unless context.respond_to?(target, true)
|
25
70
|
raise ArgumentError, ":callback_options is not defined in #{context.class}" unless context.class.respond_to?(:callback_options)
|
@@ -31,7 +76,7 @@ module ActiveFunctionCore
|
|
31
76
|
|
32
77
|
private def normalized_options(options, context)
|
33
78
|
options.map do |option|
|
34
|
-
name, arg = option
|
79
|
+
name, arg = option
|
35
80
|
-> { context.class.callback_options[name].call(arg, context:) }
|
36
81
|
end
|
37
82
|
end
|
@@ -41,6 +86,14 @@ module ActiveFunctionCore
|
|
41
86
|
super(callbacks: callbacks.to_h { [_1, []] }, **)
|
42
87
|
end
|
43
88
|
|
89
|
+
# Adds a callback to the hook.
|
90
|
+
#
|
91
|
+
# @param type [Symbol] the type of callback, `:before` or `:after`
|
92
|
+
# @param target [Symbol] the name of the callback method.
|
93
|
+
# @param options [Hash] the options for the callback.
|
94
|
+
# @options options [Symbol] :if the name of the method to check before executing the callback.
|
95
|
+
# @options options [Symbol] :unless the name of the method to check before executing the callback.
|
96
|
+
# @raise [ArgumentError] if callback already defined.
|
44
97
|
def add_callback(type:, target:, options: {})
|
45
98
|
callbacks[type] << Callback[options, target].tap do |callback|
|
46
99
|
next unless callbacks[type].map(&:hash).to_set === callback.hash
|
@@ -49,6 +102,11 @@ module ActiveFunctionCore
|
|
49
102
|
end
|
50
103
|
end
|
51
104
|
|
105
|
+
# Runs all callbacks for the hook.
|
106
|
+
#
|
107
|
+
# @param context [Object] instance of class with defined hook.
|
108
|
+
# @yield [*args] block of code around which callbacks will be executed.
|
109
|
+
# @return the result of the block.
|
52
110
|
def run_callbacks(context, &block)
|
53
111
|
callbacks[:before].each { |it| it.run(context) }
|
54
112
|
|
@@ -60,24 +118,33 @@ module ActiveFunctionCore
|
|
60
118
|
end
|
61
119
|
end
|
62
120
|
|
63
|
-
|
64
|
-
base.extend(ClassMethods)
|
65
|
-
end
|
66
|
-
|
121
|
+
# DSL method for {ActiveFunctionCore::Plugins::Hooks}
|
67
122
|
module ClassMethods
|
123
|
+
# Returns all setuped hooks for the class.
|
68
124
|
def hooks = @__hooks ||= {}
|
125
|
+
|
126
|
+
# Returns all setuped custom callback options for the class.
|
69
127
|
def callback_options = @__callback_options ||= Hook::DEFAULT_CALLBACK_OPTIONS.dup
|
70
128
|
|
129
|
+
# Inherited callback to ensure that callbacks are inherited from the base class.
|
71
130
|
def inherited(subclass)
|
72
131
|
subclass.instance_variable_set(:@__hooks, Marshal.load(Marshal.dump(hooks)))
|
73
132
|
subclass.instance_variable_set(:@__callback_options, callback_options.dup)
|
74
133
|
end
|
75
134
|
|
135
|
+
# Setups hooks for provided method.
|
76
136
|
# Redefines method providing callbacks calls around it.
|
77
|
-
# Defines
|
137
|
+
# Defines *before_[name]* and *after_[name]* methods for setting callbacks.
|
138
|
+
#
|
139
|
+
# @example
|
140
|
+
# define_hooks_for :process, name: :action
|
141
|
+
# before_action :set_first
|
142
|
+
# after_action :set_last, if: :ok?
|
78
143
|
#
|
79
144
|
# @param method [Symbol] the name of the callbackable method.
|
80
145
|
# @param name [Symbol] alias for hooked method before_[name] & after_[name] methods.
|
146
|
+
# @raise [ArgumentError] if hook for method already defined.
|
147
|
+
# @raise [ArgumentError] if method is not defined.
|
81
148
|
def define_hooks_for(method, name: method)
|
82
149
|
raise(ArgumentError, "Hook for #{method} are already defined") if hooks.key?(method)
|
83
150
|
raise(ArgumentError, "Method #{method} is not defined") unless method_defined?(method)
|
@@ -101,21 +168,35 @@ module ActiveFunctionCore
|
|
101
168
|
|
102
169
|
# Sets a callback for an existing hook'ed method.
|
103
170
|
#
|
171
|
+
# @example
|
172
|
+
# define_hooks_for :action
|
173
|
+
# set_callback :before, :action, :set_first
|
174
|
+
#
|
104
175
|
# @param type [Symbol] the type of callback, `:before` or `:after`
|
105
176
|
# @param method_name [Symbol] the name of the callbackable method.
|
106
177
|
# @param target [Symbol] the name of the callback method.
|
107
178
|
# @param options [Hash] the options for the callback.
|
108
|
-
# @
|
179
|
+
# @option options [Symbol] :if the name of the booled method to call before executing the callback.
|
180
|
+
# @option options [Symbol] :unless the name of the booled method to call before executing the callback.
|
181
|
+
# @raise [ArgumentError] if hook for provided method is not setuped via ::define_hooks_for.
|
182
|
+
# @raise [ArgumentError] if unsupported @options was passed.
|
109
183
|
def set_callback(type, method_name, target, options = {})
|
110
184
|
raise(ArgumentError, "Hook for :#{method_name} is not defined") unless hooks.key?(method_name)
|
111
|
-
raise(ArgumentError, "Hook Callback accepts only #{
|
185
|
+
raise(ArgumentError, "Hook Callback accepts only #{callback_options.keys} options") if (options.keys - callback_options.keys).any?
|
112
186
|
|
113
187
|
hooks[method_name].add_callback(type:, target:, options:)
|
114
188
|
end
|
115
189
|
|
116
190
|
# Sets a custom callback option.
|
117
191
|
#
|
118
|
-
# @
|
192
|
+
# @example
|
193
|
+
# set_callback_option only: ->(args, context:) { args.to_set === context.current_action }
|
194
|
+
# define_hooks_for :action
|
195
|
+
# before_action :set_first, only: :index
|
196
|
+
#
|
197
|
+
# @param option [Hash{Symbol => Proc}] The custom callback option as a single-value hash.
|
198
|
+
# - :name [Symbol] The name of the option.
|
199
|
+
# - :block [Proc] The block to call.
|
119
200
|
# @yield [*attrs, context:] the block to call.
|
120
201
|
# @yieldparam attrs [*] the attributes passed to the option.
|
121
202
|
# @yieldparam context [Object] the instance context (optional).
|
@@ -125,6 +206,10 @@ module ActiveFunctionCore
|
|
125
206
|
callback_options[name] = block
|
126
207
|
end
|
127
208
|
end
|
209
|
+
|
210
|
+
def self.included(base)
|
211
|
+
base.extend(ClassMethods)
|
212
|
+
end
|
128
213
|
end
|
129
214
|
end
|
130
215
|
end
|
data/lib/active_function_core.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activefunction-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nerbyk
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-01-
|
11
|
+
date: 2024-01-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ruby-next
|
@@ -34,22 +34,23 @@ files:
|
|
34
34
|
- CHANGELOG.md
|
35
35
|
- LICENSE.txt
|
36
36
|
- README.md
|
37
|
-
- lib/.rbnext/2.7/plugins/hooks.rb
|
38
|
-
- lib/.rbnext/3.0/plugins/hooks.rb
|
39
|
-
- lib/.rbnext/3.1/plugins/hooks.rb
|
40
|
-
- lib/.rbnext/3.2/plugins/hooks.rb
|
37
|
+
- lib/.rbnext/2.7/active_function_core/plugins/hooks.rb
|
38
|
+
- lib/.rbnext/3.0/active_function_core/plugins/hooks.rb
|
39
|
+
- lib/.rbnext/3.1/active_function_core/plugins/hooks.rb
|
40
|
+
- lib/.rbnext/3.2/active_function_core/plugins/hooks.rb
|
41
41
|
- lib/active_function_core.rb
|
42
|
+
- lib/active_function_core/plugins/hooks.rb
|
42
43
|
- lib/active_function_core/version.rb
|
43
|
-
- lib/plugins/hooks.rb
|
44
44
|
- sig/active_function_core.rbs
|
45
45
|
- sig/manifest.yml
|
46
46
|
homepage: https://github.com/DanilMaximov/activefunction
|
47
47
|
licenses:
|
48
48
|
- MIT
|
49
49
|
metadata:
|
50
|
-
homepage_uri: https://github.com/DanilMaximov/activefunction-core
|
51
|
-
source_code_uri: https://github.com/DanilMaximov/activefunction-core
|
52
|
-
changelog_uri: https://github.com/DanilMaximov/activefunction-core/CHANGELOG.md
|
50
|
+
homepage_uri: https://github.com/DanilMaximov/activefunction/tree/master/gems/activefunction-core
|
51
|
+
source_code_uri: https://github.com/DanilMaximov/activefunction/tree/master/gems/activefunction-core
|
52
|
+
changelog_uri: https://github.com/DanilMaximov/activefunction/tree/master/gems/activefunction-core/CHANGELOG.md
|
53
|
+
documentation_uri: https://github.com/DanilMaximov/activefunction/tree/master/gems/activefunction-core
|
53
54
|
post_install_message:
|
54
55
|
rdoc_options: []
|
55
56
|
require_paths:
|
@@ -65,7 +66,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
65
66
|
- !ruby/object:Gem::Version
|
66
67
|
version: '0'
|
67
68
|
requirements: []
|
68
|
-
rubygems_version: 3.
|
69
|
+
rubygems_version: 3.5.4
|
69
70
|
signing_key:
|
70
71
|
specification_version: 4
|
71
72
|
summary: ActiveFunction core gem
|