rails-workflow 1.4.5.4 → 1.4.6.4
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/.gitignore +2 -0
- data/.rubocop.yml +23 -0
- data/Gemfile +2 -1
- data/Rakefile +4 -4
- data/bin/console +3 -3
- data/lib/active_support/overloads.rb +13 -6
- data/lib/workflow.rb +12 -279
- data/lib/workflow/adapters/active_record.rb +57 -50
- data/lib/workflow/adapters/active_record_validations.rb +25 -19
- data/lib/workflow/adapters/adapter.rb +23 -0
- data/lib/workflow/adapters/remodel.rb +8 -9
- data/lib/workflow/callbacks.rb +60 -45
- data/lib/workflow/callbacks/callback.rb +23 -37
- data/lib/workflow/callbacks/method_callback.rb +12 -0
- data/lib/workflow/callbacks/proc_callback.rb +23 -0
- data/lib/workflow/callbacks/string_callback.rb +12 -0
- data/lib/workflow/callbacks/transition_callback.rb +88 -78
- data/lib/workflow/callbacks/transition_callbacks/method_caller.rb +53 -0
- data/lib/workflow/callbacks/transition_callbacks/proc_caller.rb +60 -0
- data/lib/workflow/configuration.rb +1 -0
- data/lib/workflow/definition.rb +73 -0
- data/lib/workflow/errors.rb +37 -6
- data/lib/workflow/event.rb +30 -15
- data/lib/workflow/helper_method_configurator.rb +100 -0
- data/lib/workflow/specification.rb +45 -22
- data/lib/workflow/state.rb +45 -36
- data/lib/workflow/transition_context.rb +5 -4
- data/lib/workflow/transitions.rb +94 -0
- data/lib/workflow/version.rb +2 -1
- data/rails-workflow.gemspec +18 -18
- data/tags.markdown +31 -0
- metadata +13 -5
- data/lib/workflow/callbacks/transition_callbacks/method_wrapper.rb +0 -102
- data/lib/workflow/callbacks/transition_callbacks/proc_wrapper.rb +0 -48
- data/lib/workflow/draw.rb +0 -79
data/lib/workflow/state.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Workflow
|
2
3
|
# Represents one state for the defined workflow,
|
3
4
|
# with a list of {Workflow::Event}s that can transition to
|
@@ -11,35 +12,45 @@ module Workflow
|
|
11
12
|
# @return [Array] Array of {Workflow::Event}s defined for this state.
|
12
13
|
# @!attribute [r] meta
|
13
14
|
# @return [Hash] Extra information defined for this state.
|
14
|
-
|
15
|
+
# @!attribute [r] tags
|
16
|
+
# @return [Array] Tags for this state.
|
17
|
+
attr_reader :name, :events, :meta, :tags
|
15
18
|
|
16
19
|
# @api private
|
17
20
|
# For creating {Workflow::State} objects please see {Specification#state}
|
18
|
-
# @param [Symbol] name
|
19
|
-
# @param [Fixnum] sequence
|
20
|
-
# @param [Hash] meta
|
21
|
-
def initialize(name, sequence, meta: {})
|
22
|
-
@name
|
21
|
+
# @param [Symbol] name Name of the state being created. Must be unique within its workflow.
|
22
|
+
# @param [Fixnum] sequence Sort location among states on this workflow.
|
23
|
+
# @param [Hash] meta Optional metadata for this state.
|
24
|
+
def initialize(name, sequence, tags: [], meta: {})
|
25
|
+
@name = name.to_sym
|
26
|
+
@sequence = sequence
|
27
|
+
@events = []
|
28
|
+
@meta = meta
|
29
|
+
@tags = [tags].flatten
|
30
|
+
unless @tags.reject { |t| t.is_a? Symbol }
|
31
|
+
raise WorkflowDefinitionError, "Tags can only include symbols, state: #{name}"
|
32
|
+
end
|
23
33
|
end
|
24
34
|
|
25
35
|
# Returns the event with the given name.
|
26
36
|
# @param [Symbol] name name of event to find
|
27
37
|
# @return [Workflow::Event] The event with the given name, or `nil`
|
28
38
|
def find_event(name)
|
29
|
-
events.find{|t| t.name == name}
|
39
|
+
events.find { |t| t.name == name }
|
30
40
|
end
|
31
41
|
|
32
42
|
# Define an event on this specification.
|
33
|
-
# Must be called within the scope of the block within a call to {#state}.
|
43
|
+
# Must be called within the scope of the block within a call to {Workflow::Specification#state}.
|
34
44
|
#
|
35
45
|
# @param [Symbol] name The name of the event
|
36
|
-
# @param [Symbol] to
|
37
|
-
#
|
46
|
+
# @param [Symbol] to Optional name of {Workflow::State} this event will transition to.
|
47
|
+
# Must be omitted if a block is provided.
|
48
|
+
# @param [Hash] meta Optional hash of metadata to be stored on the event object.
|
38
49
|
# @yield [] Transitions definition for this event.
|
39
50
|
# @return [nil]
|
40
51
|
#
|
41
|
-
|
42
|
-
#workflow do
|
52
|
+
# ```ruby
|
53
|
+
# workflow do
|
43
54
|
# state :new do
|
44
55
|
# on :review, to: :being_reviewed
|
45
56
|
#
|
@@ -58,21 +69,10 @@ module Workflow
|
|
58
69
|
# state :kitchen
|
59
70
|
# state :the_bar
|
60
71
|
# state :the_diner
|
61
|
-
#end
|
62
|
-
|
72
|
+
# end
|
73
|
+
# ```
|
63
74
|
def on(name, to: nil, meta: {}, &transitions)
|
64
|
-
|
65
|
-
raise Errors::WorkflowDefinitionError.new("Event target can only be received in the method call or the block, not both.")
|
66
|
-
end
|
67
|
-
|
68
|
-
unless to || block_given?
|
69
|
-
raise Errors::WorkflowDefinitionError.new("No event target given for event #{name}")
|
70
|
-
end
|
71
|
-
|
72
|
-
if find_event(name)
|
73
|
-
raise Errors::WorkflowDefinitionError.new("Already defined an event [#{name}] for state[#{self.name}]")
|
74
|
-
end
|
75
|
-
|
75
|
+
check_can_add_transition!(name, to: to, &transitions)
|
76
76
|
event = Workflow::Event.new(name, meta: meta)
|
77
77
|
|
78
78
|
if to
|
@@ -81,14 +81,24 @@ module Workflow
|
|
81
81
|
event.instance_eval(&transitions)
|
82
82
|
end
|
83
83
|
|
84
|
-
|
85
|
-
raise Errors::
|
84
|
+
unless event.valid?
|
85
|
+
raise Errors::NoTransitionsDefinedError.new(self, event)
|
86
86
|
end
|
87
87
|
|
88
88
|
events << event
|
89
89
|
nil
|
90
90
|
end
|
91
91
|
|
92
|
+
private def check_can_add_transition!(name, to: nil)
|
93
|
+
raise Errors::DualEventDefinitionError if to && block_given?
|
94
|
+
|
95
|
+
unless to || block_given?
|
96
|
+
raise Errors::WorkflowDefinitionError, "No event target given for event #{name}"
|
97
|
+
end
|
98
|
+
|
99
|
+
raise Errors::EventNameCollisionError.new(self, name) if find_event(name)
|
100
|
+
end
|
101
|
+
|
92
102
|
# @return [String] String representation of object
|
93
103
|
def inspect
|
94
104
|
"<State name=#{name.inspect} events(#{events.length})=#{events.inspect}>"
|
@@ -97,20 +107,19 @@ module Workflow
|
|
97
107
|
# Overloaded comparison operator. Workflow states are sorted according to the order
|
98
108
|
# in which they were defined.
|
99
109
|
#
|
100
|
-
# @param [Workflow::State]
|
110
|
+
# @param [Workflow::State] other state to be compared against.
|
101
111
|
# @return [Integer]
|
102
|
-
def <=>(
|
103
|
-
unless
|
104
|
-
|
105
|
-
end
|
106
|
-
self.sequence <=> other_state.send(:sequence)
|
112
|
+
def <=>(other)
|
113
|
+
raise Errors::StateComparisonError, other unless other.is_a?(State)
|
114
|
+
sequence <=> other.send(:sequence)
|
107
115
|
end
|
108
116
|
|
109
117
|
private
|
118
|
+
|
110
119
|
# @api private
|
111
120
|
# @!attribute [r] sequence
|
112
|
-
# @return [Fixnum] The position of this state within the
|
121
|
+
# @return [Fixnum] The position of this state within the
|
122
|
+
# order it was defined for in its workflow.
|
113
123
|
attr_reader :sequence
|
114
|
-
|
115
124
|
end
|
116
125
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Workflow
|
2
3
|
# During transitions, an instance of this class can be found
|
3
4
|
# on the object as `transition_context`.
|
@@ -30,20 +31,20 @@ module Workflow
|
|
30
31
|
# If you pass fewer parameters, the later ones will simply be nil.
|
31
32
|
class TransitionContext
|
32
33
|
attr_reader :from, :to, :event, :event_args, :attributes, :named_arguments
|
33
|
-
def initialize(from:, to:, event:, event_args:,
|
34
|
+
def initialize(from:, to:, event:, event_args:, **args)
|
34
35
|
@from = from
|
35
36
|
@to = to
|
36
37
|
@event = event
|
37
38
|
@event_args = event_args
|
38
|
-
@attributes = attributes
|
39
|
-
@named_arguments = (named_arguments || []).zip(event_args).to_h
|
39
|
+
@attributes = args[:attributes] || {}
|
40
|
+
@named_arguments = (args[:named_arguments] || []).zip(event_args).to_h
|
40
41
|
end
|
41
42
|
|
42
43
|
def values
|
43
44
|
[from, to, event, event_args.dup, attributes.dup]
|
44
45
|
end
|
45
46
|
|
46
|
-
def
|
47
|
+
def respond_to_missing?(method, _include_private = false)
|
47
48
|
named_arguments.key?(method) || super
|
48
49
|
end
|
49
50
|
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Workflow
|
3
|
+
module Transitions
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
# @api private
|
7
|
+
# @!attribute [r] transition_context
|
8
|
+
# @return [Workflow::TransitionContext] During transition, or nil if no transition is underway.
|
9
|
+
# During a state transition, contains transition-specific information:
|
10
|
+
# * The name of the {Workflow::State} being exited,
|
11
|
+
# * The name of the {Workflow::State} being entered,
|
12
|
+
# * The name of the {Workflow::Event} that was fired,
|
13
|
+
# * And whatever arguments were passed to the {Workflow#transition!} method.
|
14
|
+
included do
|
15
|
+
attr_reader :transition_context
|
16
|
+
end
|
17
|
+
|
18
|
+
# Initiates state transition via the named event
|
19
|
+
#
|
20
|
+
# @param [Symbol] name name of event to initiate
|
21
|
+
# @param [Array] args State transition arguments.
|
22
|
+
# @return [Symbol] The name of the new state, or `false` if the transition failed.
|
23
|
+
# TODO: connect args to documentation on how arguments are accessed during state transitions.
|
24
|
+
def transition!(name, *args, **attributes)
|
25
|
+
@transition_context = prepare_transition(name, args, attributes)
|
26
|
+
|
27
|
+
run_all_callbacks do
|
28
|
+
persist_workflow_state(@transition_context.to)
|
29
|
+
end
|
30
|
+
ensure
|
31
|
+
@transition_context = nil
|
32
|
+
end
|
33
|
+
|
34
|
+
# Stop the current transition and set the reason for the abort.
|
35
|
+
#
|
36
|
+
# @param [String] reason Optional reason for halting transition.
|
37
|
+
# @return [nil]
|
38
|
+
def halt(reason = nil)
|
39
|
+
@halted_because = reason
|
40
|
+
@halted = true
|
41
|
+
throw :abort
|
42
|
+
end
|
43
|
+
|
44
|
+
# Sets halt reason and raises [TransitionHaltedError] error.
|
45
|
+
#
|
46
|
+
# @param [String] reason Optional reason for halting
|
47
|
+
# @return [nil]
|
48
|
+
def halt!(reason = nil)
|
49
|
+
@halted_because = reason
|
50
|
+
@halted = true
|
51
|
+
raise Errors::TransitionHaltedError, reason
|
52
|
+
end
|
53
|
+
|
54
|
+
# Deprecated. Check for false return value from {#transition!}
|
55
|
+
# @return [Boolean] true if the last transition was halted by one of the transition callbacks.
|
56
|
+
def halted?
|
57
|
+
@halted
|
58
|
+
end
|
59
|
+
|
60
|
+
# Returns the reason given to a call to {#halt} or {#halt!}, if any.
|
61
|
+
# @return [String] The reason the transition was aborted.
|
62
|
+
attr_reader :halted_because
|
63
|
+
|
64
|
+
# load_workflow_state and persist_workflow_state
|
65
|
+
# can be overriden to handle the persistence of the workflow state.
|
66
|
+
#
|
67
|
+
# Default (non ActiveRecord) implementation stores the current state
|
68
|
+
# in a variable.
|
69
|
+
#
|
70
|
+
# Default ActiveRecord implementation uses a 'workflow_state' database column.
|
71
|
+
def load_workflow_state
|
72
|
+
@workflow_state if instance_variable_defined? :@workflow_state
|
73
|
+
end
|
74
|
+
|
75
|
+
def persist_workflow_state(new_value)
|
76
|
+
@workflow_state = new_value
|
77
|
+
end
|
78
|
+
|
79
|
+
def prepare_transition(name, args, attributes)
|
80
|
+
event = current_state.find_event(name.to_sym)
|
81
|
+
raise Errors::NoTransitionAllowed.new(current_state, name) unless event
|
82
|
+
|
83
|
+
target = event.evaluate(self)
|
84
|
+
|
85
|
+
TransitionContext.new \
|
86
|
+
from: current_state.name,
|
87
|
+
to: target.name,
|
88
|
+
event: event.name,
|
89
|
+
event_args: args,
|
90
|
+
attributes: attributes,
|
91
|
+
named_arguments: workflow_spec.named_arguments
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
data/lib/workflow/version.rb
CHANGED
data/rails-workflow.gemspec
CHANGED
@@ -1,41 +1,42 @@
|
|
1
1
|
# coding: utf-8
|
2
|
+
# frozen_string_literal: true
|
2
3
|
lib = File.expand_path('../lib', __FILE__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
5
|
require 'workflow/version'
|
5
6
|
Gem::Specification.new do |spec|
|
6
|
-
spec.name =
|
7
|
+
spec.name = 'rails-workflow'
|
7
8
|
spec.version = Workflow::VERSION
|
8
|
-
spec.authors = [
|
9
|
-
spec.email = [
|
9
|
+
spec.authors = ['Tyler Gannon']
|
10
|
+
spec.email = ['tyler@aprilseven.co']
|
10
11
|
|
11
|
-
spec.summary =
|
12
|
-
spec.description =
|
13
|
-
spec.homepage =
|
14
|
-
spec.license =
|
12
|
+
spec.summary = "A finite-state-machine-inspired API for managing state changes in ActiveModel objects. Based on Vladimir Dobriakov's Workflow gem (https://github.com/geekq/workflow)"
|
13
|
+
spec.description = 'Workflow specifically for ActiveModel objects.'
|
14
|
+
spec.homepage = 'https://tylergannon.github.io/rails-workflow/'
|
15
|
+
spec.license = 'MIT'
|
15
16
|
|
16
17
|
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
17
18
|
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
18
19
|
if spec.respond_to?(:metadata)
|
19
|
-
spec.metadata['allowed_push_host'] =
|
20
|
+
spec.metadata['allowed_push_host'] = 'https://rubygems.org'
|
20
21
|
else
|
21
|
-
raise
|
22
|
-
|
22
|
+
raise 'RubyGems 2.0 or newer is required to protect against ' \
|
23
|
+
'public gem pushes.'
|
23
24
|
end
|
24
25
|
|
25
|
-
spec.files
|
26
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
26
27
|
f.match(%r{^(test|spec|features|doc)/})
|
27
28
|
end
|
28
|
-
spec.bindir =
|
29
|
+
spec.bindir = 'exe'
|
29
30
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
30
|
-
spec.require_paths = [
|
31
|
+
spec.require_paths = ['lib']
|
31
32
|
spec.extra_rdoc_files = [
|
32
|
-
|
33
|
+
'README.markdown'
|
33
34
|
]
|
34
35
|
|
35
36
|
spec.add_dependency 'activerecord', '~> 5.0'
|
36
37
|
spec.add_dependency 'activesupport', '~> 5.0'
|
37
38
|
|
38
|
-
spec.add_development_dependency 'rdoc',
|
39
|
+
spec.add_development_dependency 'rdoc', ['>= 3.12']
|
39
40
|
spec.add_development_dependency 'sqlite3'
|
40
41
|
spec.add_development_dependency 'mocha'
|
41
42
|
spec.add_development_dependency 'yard'
|
@@ -44,8 +45,7 @@ Gem::Specification.new do |spec|
|
|
44
45
|
spec.add_development_dependency 'rake'
|
45
46
|
spec.add_development_dependency 'test-unit'
|
46
47
|
spec.add_development_dependency 'ruby-graphviz', ['~> 1.0.0']
|
47
|
-
spec.add_development_dependency
|
48
|
-
spec.add_development_dependency
|
48
|
+
spec.add_development_dependency 'bundler', '~> 1.13'
|
49
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
49
50
|
spec.required_ruby_version = '>= 2.3'
|
50
|
-
|
51
51
|
end
|
data/tags.markdown
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
---
|
2
|
+
layout: page
|
3
|
+
---
|
4
|
+
|
5
|
+
# Tagging States
|
6
|
+
|
7
|
+
Place your workflow states into groups by tagging them.
|
8
|
+
Also note the helper methods `initial?` and `terminal?`.
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
class Foo
|
12
|
+
include Workflow
|
13
|
+
state :new, tags: :bar do
|
14
|
+
on :complete, to: :completed
|
15
|
+
end
|
16
|
+
state :completed, tags: [:awesome, :congrats]
|
17
|
+
end
|
18
|
+
|
19
|
+
a = Foo.new
|
20
|
+
a.current_state.bar?
|
21
|
+
# => true
|
22
|
+
a.current_state.initial?
|
23
|
+
# => true
|
24
|
+
a.awesome?
|
25
|
+
# => false
|
26
|
+
a.transition! :complete
|
27
|
+
a.terminal?
|
28
|
+
# => true
|
29
|
+
a.awesome?
|
30
|
+
# => true
|
31
|
+
```
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rails-workflow
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.4.
|
4
|
+
version: 1.4.6.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tyler Gannon
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-09-
|
11
|
+
date: 2016-09-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -201,6 +201,7 @@ extra_rdoc_files:
|
|
201
201
|
- README.markdown
|
202
202
|
files:
|
203
203
|
- ".gitignore"
|
204
|
+
- ".rubocop.yml"
|
204
205
|
- ".travis.yml"
|
205
206
|
- ".yardopts"
|
206
207
|
- Gemfile
|
@@ -219,22 +220,29 @@ files:
|
|
219
220
|
- lib/workflow.rb
|
220
221
|
- lib/workflow/adapters/active_record.rb
|
221
222
|
- lib/workflow/adapters/active_record_validations.rb
|
223
|
+
- lib/workflow/adapters/adapter.rb
|
222
224
|
- lib/workflow/adapters/remodel.rb
|
223
225
|
- lib/workflow/callbacks.rb
|
224
226
|
- lib/workflow/callbacks/callback.rb
|
227
|
+
- lib/workflow/callbacks/method_callback.rb
|
228
|
+
- lib/workflow/callbacks/proc_callback.rb
|
229
|
+
- lib/workflow/callbacks/string_callback.rb
|
225
230
|
- lib/workflow/callbacks/transition_callback.rb
|
226
|
-
- lib/workflow/callbacks/transition_callbacks/
|
227
|
-
- lib/workflow/callbacks/transition_callbacks/
|
231
|
+
- lib/workflow/callbacks/transition_callbacks/method_caller.rb
|
232
|
+
- lib/workflow/callbacks/transition_callbacks/proc_caller.rb
|
228
233
|
- lib/workflow/configuration.rb
|
229
|
-
- lib/workflow/
|
234
|
+
- lib/workflow/definition.rb
|
230
235
|
- lib/workflow/errors.rb
|
231
236
|
- lib/workflow/event.rb
|
237
|
+
- lib/workflow/helper_method_configurator.rb
|
232
238
|
- lib/workflow/specification.rb
|
233
239
|
- lib/workflow/state.rb
|
234
240
|
- lib/workflow/transition_context.rb
|
241
|
+
- lib/workflow/transitions.rb
|
235
242
|
- lib/workflow/version.rb
|
236
243
|
- orders_workflow.png
|
237
244
|
- rails-workflow.gemspec
|
245
|
+
- tags.markdown
|
238
246
|
homepage: https://tylergannon.github.io/rails-workflow/
|
239
247
|
licenses:
|
240
248
|
- MIT
|
@@ -1,102 +0,0 @@
|
|
1
|
-
module Workflow
|
2
|
-
module Callbacks
|
3
|
-
module TransitionCallbacks
|
4
|
-
# A {Workflow::Callbacks::TransitionCallback} that wraps an instance method
|
5
|
-
# With arity != 0.
|
6
|
-
# Because the wrapped method may not have been defined at the time the callback
|
7
|
-
# is defined, the string representing the method call is built at runtime
|
8
|
-
# rather than at compile time.
|
9
|
-
class MethodWrapper < ::Workflow::Callbacks::TransitionCallback
|
10
|
-
attr_reader :calling_class
|
11
|
-
|
12
|
-
# Builds a proc object that will correctly call the {#raw_proc}
|
13
|
-
# by inspecting its parameters and pulling arguments from the {Workflow::TransitionContext}
|
14
|
-
# object for the transition.
|
15
|
-
# Given an overloaded `==` operator so for {Workflow#skip_before_transition} and other
|
16
|
-
# `skip_transition` calls.
|
17
|
-
# @return [Type] description of returned object
|
18
|
-
def wrapper
|
19
|
-
cb_object = self
|
20
|
-
proc_string = build_proc(<<-EOF)
|
21
|
-
arguments = [
|
22
|
-
cb_object.send(:raw_proc).inspect,
|
23
|
-
cb_object.send(:name_arguments_string),
|
24
|
-
cb_object.send(:rest_param_string),
|
25
|
-
cb_object.send(:kw_arguments_string),
|
26
|
-
cb_object.send(:keyrest_string),
|
27
|
-
cb_object.send(:procedure_string)].compact.join(', ')
|
28
|
-
target.instance_eval("send(\#{arguments})")
|
29
|
-
EOF
|
30
|
-
_wrapper = eval(proc_string)
|
31
|
-
_wrapper.instance_exec(raw_proc, &OVERLOAD_EQUALITY_OPERATOR_PROC)
|
32
|
-
_wrapper
|
33
|
-
end
|
34
|
-
|
35
|
-
private
|
36
|
-
|
37
|
-
# A that is instanced_exec'd on a new proc object within {#wrapper}
|
38
|
-
#
|
39
|
-
# Enables comparison of two wrapper procs to determine if they wrap the same
|
40
|
-
# Method.
|
41
|
-
OVERLOAD_EQUALITY_OPERATOR_PROC = Proc.new do |method_name|
|
42
|
-
def method_name
|
43
|
-
method_name
|
44
|
-
end
|
45
|
-
|
46
|
-
# Equality operator overload.
|
47
|
-
# If other is a {Symbol}, matches this object against {#method_name} defined above.
|
48
|
-
# If other is a {Proc}:
|
49
|
-
# * If it responds to {#method_name}, matches the method names of the two objects.
|
50
|
-
# * Otherwise false
|
51
|
-
#
|
52
|
-
# @param [Symbol] other A method name to compare against.
|
53
|
-
# @param [Proc] other A proc to compare against.
|
54
|
-
# @return [Boolean] Whether the two should be considered equivalent
|
55
|
-
def ==(other)
|
56
|
-
case other
|
57
|
-
when ::Proc
|
58
|
-
if other.respond_to?(:raw_proc)
|
59
|
-
self.method_name == other.method_name
|
60
|
-
else
|
61
|
-
false
|
62
|
-
end
|
63
|
-
when ::Symbol
|
64
|
-
self.method_name == other
|
65
|
-
else
|
66
|
-
false
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
def name_arguments_string
|
72
|
-
if name_params.any?
|
73
|
-
name_params.map{|name|
|
74
|
-
"name_proc.call(:#{name})"
|
75
|
-
}.join(', ')
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
def procedure_string
|
80
|
-
'&callbacks' if around_callback?
|
81
|
-
end
|
82
|
-
|
83
|
-
# @return [UnboundMethod] Method representation from class {#calling_class}, named by {#raw_proc}
|
84
|
-
def callback_method
|
85
|
-
@meth ||= calling_class.instance_method(raw_proc)
|
86
|
-
end
|
87
|
-
|
88
|
-
# Parameter definition for the object. See {UnboundMethod#parameters}
|
89
|
-
#
|
90
|
-
# @return [Array] Parameters
|
91
|
-
def parameters
|
92
|
-
callback_method.parameters
|
93
|
-
end
|
94
|
-
|
95
|
-
# @return [Fixnum] Arity of the callback method
|
96
|
-
def arity
|
97
|
-
callback_method.arity
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|