gamefic 3.4.0 → 3.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -0
- data/README.md +1 -1
- data/lib/gamefic/active/epic.rb +1 -0
- data/lib/gamefic/active.rb +4 -0
- data/lib/gamefic/chapter.rb +25 -42
- data/lib/gamefic/command.rb +40 -1
- data/lib/gamefic/dispatcher.rb +5 -31
- data/lib/gamefic/entity.rb +26 -0
- data/lib/gamefic/narrative.rb +9 -5
- data/lib/gamefic/plot.rb +5 -0
- data/lib/gamefic/proxy.rb +46 -0
- data/lib/gamefic/query/base.rb +28 -12
- data/lib/gamefic/query/general.rb +3 -12
- data/lib/gamefic/query/result.rb +4 -1
- data/lib/gamefic/query/scoped.rb +1 -18
- data/lib/gamefic/query/text.rb +13 -12
- data/lib/gamefic/response.rb +65 -34
- data/lib/gamefic/scanner/base.rb +44 -0
- data/lib/gamefic/scanner/fuzzy.rb +17 -0
- data/lib/gamefic/scanner/fuzzy_nesting.rb +14 -0
- data/lib/gamefic/scanner/nesting.rb +39 -0
- data/lib/gamefic/scanner/result.rb +50 -0
- data/lib/gamefic/scanner/strict.rb +31 -0
- data/lib/gamefic/scanner.rb +33 -111
- data/lib/gamefic/scope/descendants.rb +16 -0
- data/lib/gamefic/scope/family.rb +31 -8
- data/lib/gamefic/scope.rb +1 -0
- data/lib/gamefic/scriptable/actions.rb +4 -23
- data/lib/gamefic/scriptable/entities.rb +4 -1
- data/lib/gamefic/scriptable/plot_proxies.rb +16 -0
- data/lib/gamefic/scriptable/proxies.rb +31 -0
- data/lib/gamefic/scriptable/queries.rb +15 -7
- data/lib/gamefic/scriptable/scenes.rb +7 -1
- data/lib/gamefic/scriptable.rb +67 -15
- data/lib/gamefic/stage.rb +2 -2
- data/lib/gamefic/subplot.rb +27 -1
- data/lib/gamefic/version.rb +1 -1
- data/lib/gamefic.rb +1 -1
- metadata +12 -4
- data/lib/gamefic/composer.rb +0 -70
- data/lib/gamefic/scriptable/proxy.rb +0 -69
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Gamefic
|
4
|
+
module Scriptable
|
5
|
+
# Methods for referencing entities from proxies.
|
6
|
+
#
|
7
|
+
module Proxies
|
8
|
+
# Convert a proxy into its referenced entity.
|
9
|
+
#
|
10
|
+
# This method can receive any kind of object. If it's a proxy, its entity
|
11
|
+
# will be returned. If it's an array, each of its elements will be
|
12
|
+
# unproxied. If it's a hash, each of its values will be unproxied. Any
|
13
|
+
# other object will be returned unchanged.
|
14
|
+
#
|
15
|
+
# @param object [Object]
|
16
|
+
# @return [Object]
|
17
|
+
def unproxy object
|
18
|
+
case object
|
19
|
+
when Proxy
|
20
|
+
object.fetch self
|
21
|
+
when Array
|
22
|
+
object.map { |obj| unproxy obj }
|
23
|
+
when Hash
|
24
|
+
object.transform_values { |val| unproxy val }
|
25
|
+
else
|
26
|
+
object
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -5,14 +5,14 @@ module Gamefic
|
|
5
5
|
# Scriptable methods related to creating action queries.
|
6
6
|
#
|
7
7
|
module Queries
|
8
|
-
include
|
8
|
+
include Proxies
|
9
9
|
|
10
10
|
# Define a query that searches the entire plot's entities.
|
11
11
|
#
|
12
12
|
# @param args [Array<Object>] Query arguments
|
13
13
|
# @return [Query::General]
|
14
14
|
def anywhere *args, ambiguous: false
|
15
|
-
Query::General.new -> { entities }, *
|
15
|
+
Query::General.new -> { entities }, *args, ambiguous: ambiguous
|
16
16
|
end
|
17
17
|
|
18
18
|
# Define a query that searches an actor's family of entities. The
|
@@ -22,7 +22,7 @@ module Gamefic
|
|
22
22
|
# @param args [Array<Object>] Query arguments
|
23
23
|
# @return [Query::Scoped]
|
24
24
|
def available *args, ambiguous: false
|
25
|
-
Query::Scoped.new Scope::Family, *
|
25
|
+
Query::Scoped.new Scope::Family, *args, ambiguous: ambiguous
|
26
26
|
end
|
27
27
|
alias family available
|
28
28
|
|
@@ -31,7 +31,7 @@ module Gamefic
|
|
31
31
|
# @param args [Array<Object>] Query arguments
|
32
32
|
# @return [Query::Scoped]
|
33
33
|
def parent *args, ambiguous: false
|
34
|
-
Query::Scoped.new Scope::Parent, *
|
34
|
+
Query::Scoped.new Scope::Parent, *args, ambiguous: ambiguous
|
35
35
|
end
|
36
36
|
|
37
37
|
# Define a query that searches an actor's children.
|
@@ -39,7 +39,15 @@ module Gamefic
|
|
39
39
|
# @param args [Array<Object>] Query arguments
|
40
40
|
# @return [Query::Scoped]
|
41
41
|
def children *args, ambiguous: false
|
42
|
-
Query::Scoped.new Scope::Children, *
|
42
|
+
Query::Scoped.new Scope::Children, *args, ambiguous: ambiguous
|
43
|
+
end
|
44
|
+
|
45
|
+
# Define a query that searches an actor's descendants.
|
46
|
+
#
|
47
|
+
# @param args [Array<Object>] Query arguments
|
48
|
+
# @return [Query::Scoped]
|
49
|
+
def descendants *args, ambiguous: false
|
50
|
+
Query::Scoped.new Scope::Descendants, *args, ambiguous: ambiguous
|
43
51
|
end
|
44
52
|
|
45
53
|
# Define a query that searches an actor's siblings.
|
@@ -47,7 +55,7 @@ module Gamefic
|
|
47
55
|
# @param args [Array<Object>] Query arguments
|
48
56
|
# @return [Query::Scoped]
|
49
57
|
def siblings *args, ambiguous: false
|
50
|
-
Query::Scoped.new Scope::Siblings, *
|
58
|
+
Query::Scoped.new Scope::Siblings, *args, ambiguous: ambiguous
|
51
59
|
end
|
52
60
|
|
53
61
|
# Define a query that returns the actor itself.
|
@@ -55,7 +63,7 @@ module Gamefic
|
|
55
63
|
# @param args [Array<Object>] Query arguments
|
56
64
|
# @return [Query::Scoped]
|
57
65
|
def myself *args, ambiguous: false
|
58
|
-
Query::Scoped.new Scope::Myself, *
|
66
|
+
Query::Scoped.new Scope::Myself, *args, ambiguous: ambiguous
|
59
67
|
end
|
60
68
|
|
61
69
|
# Define a query that performs a plaintext search. It can take a String
|
@@ -36,7 +36,6 @@ module Gamefic
|
|
36
36
|
rulebook.scenes.add klass.new(name, self, on_start: on_start, on_finish: on_finish, &blk)
|
37
37
|
name
|
38
38
|
end
|
39
|
-
alias scene block
|
40
39
|
|
41
40
|
def preface name, klass = Scene::Activity, &start
|
42
41
|
rulebook.scenes.add klass.new(name, self, on_start: start)
|
@@ -160,9 +159,16 @@ module Gamefic
|
|
160
159
|
on_start: start
|
161
160
|
end
|
162
161
|
|
162
|
+
# @return [Array<Symbol>]
|
163
163
|
def scenes
|
164
164
|
rulebook.scenes.names
|
165
165
|
end
|
166
|
+
|
167
|
+
# @param name [Symbol]
|
168
|
+
# @return [Scene::Default, nil]
|
169
|
+
def scene(name)
|
170
|
+
rulebook.scenes[name]
|
171
|
+
end
|
166
172
|
end
|
167
173
|
end
|
168
174
|
end
|
data/lib/gamefic/scriptable.rb
CHANGED
@@ -23,14 +23,14 @@ module Gamefic
|
|
23
23
|
# end
|
24
24
|
#
|
25
25
|
module Scriptable
|
26
|
-
autoload :Actions,
|
27
|
-
autoload :Entities,
|
28
|
-
autoload :Events,
|
29
|
-
autoload :Queries,
|
30
|
-
autoload :
|
31
|
-
autoload :Scenes,
|
32
|
-
|
33
|
-
|
26
|
+
autoload :Actions, 'gamefic/scriptable/actions'
|
27
|
+
autoload :Entities, 'gamefic/scriptable/entities'
|
28
|
+
autoload :Events, 'gamefic/scriptable/events'
|
29
|
+
autoload :Queries, 'gamefic/scriptable/queries'
|
30
|
+
autoload :Proxies, 'gamefic/scriptable/proxies'
|
31
|
+
autoload :Scenes, 'gamefic/scriptable/scenes'
|
32
|
+
autoload :PlotProxies, 'gamefic/scriptable/plot_proxies'
|
33
|
+
|
34
34
|
include Queries
|
35
35
|
# @!parse
|
36
36
|
# include Scriptable::Actions
|
@@ -101,10 +101,10 @@ module Gamefic
|
|
101
101
|
# make_seed Gamefic::Entity, name: 'thing'
|
102
102
|
#
|
103
103
|
# @param klass [Class<Gamefic::Entity>]
|
104
|
+
# @return [void]
|
104
105
|
def make_seed klass, **opts
|
105
|
-
@count ||= 0
|
106
106
|
seed { make(klass, **opts) }
|
107
|
-
|
107
|
+
nil
|
108
108
|
end
|
109
109
|
|
110
110
|
# Seed an entity with an attribute method.
|
@@ -119,15 +119,67 @@ module Gamefic
|
|
119
119
|
#
|
120
120
|
# @param name [Symbol] The attribute name
|
121
121
|
# @param klass [Class<Gamefic::Entity>]
|
122
|
+
# @return [Proxy]
|
122
123
|
def attr_seed name, klass, **opts
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
124
|
+
ivname = "@#{name}"
|
125
|
+
define_method(name) do
|
126
|
+
return instance_variable_get(ivname) if instance_variable_defined?(ivname)
|
127
|
+
|
128
|
+
instance_variable_set(ivname, make(klass, **opts))
|
129
|
+
end
|
130
|
+
seed { send name }
|
131
|
+
Proxy.new(:attr, name)
|
132
|
+
end
|
133
|
+
|
134
|
+
# @param symbol [Symbol]
|
135
|
+
# @return [Proxy]
|
136
|
+
def proxy symbol
|
137
|
+
Logging.logger.warn "#proxy is deprecated. Use lazy_attr, lazy_ivar, or lazy_pick instead"
|
138
|
+
if symbol.to_s.start_with?('@')
|
139
|
+
lazy_ivar(symbol)
|
140
|
+
else
|
141
|
+
lazy_attr(symbol)
|
127
142
|
end
|
128
|
-
Proxy::Agent.new(@count.tap { @count += 1 })
|
129
143
|
end
|
130
144
|
|
145
|
+
# Lazy reference an entity by its instance variable.
|
146
|
+
#
|
147
|
+
# @example
|
148
|
+
# lazy_ivar(:@variable)
|
149
|
+
#
|
150
|
+
# @param key [Symbol]
|
151
|
+
# @return [Proxy]
|
152
|
+
def lazy_ivar key
|
153
|
+
Proxy.new(:ivar, key)
|
154
|
+
end
|
155
|
+
alias _ivar lazy_ivar
|
156
|
+
|
157
|
+
# Lazy reference an entity by its attribute or method.
|
158
|
+
#
|
159
|
+
# @example
|
160
|
+
# lazy_attr(:method)
|
161
|
+
#
|
162
|
+
# @param key [Symbol]
|
163
|
+
# @return [Proxy]
|
164
|
+
def lazy_attr key
|
165
|
+
Proxy.new(:attr, key)
|
166
|
+
end
|
167
|
+
alias _attr lazy_attr
|
168
|
+
|
169
|
+
# Lazy reference an entity by its description.
|
170
|
+
#
|
171
|
+
# @example
|
172
|
+
# lazy_pick('the red box')
|
173
|
+
#
|
174
|
+
# @raise [RuntimeError] if a unique match could not be found.
|
175
|
+
#
|
176
|
+
# @param description [String]
|
177
|
+
# @return [Proxy]
|
178
|
+
def lazy_pick description
|
179
|
+
Proxy.new(:pick, description)
|
180
|
+
end
|
181
|
+
alias _pick lazy_pick
|
182
|
+
|
131
183
|
if RUBY_ENGINE == 'opal'
|
132
184
|
# :nocov:
|
133
185
|
def method_missing method, *args, &block
|
data/lib/gamefic/stage.rb
CHANGED
@@ -14,7 +14,7 @@ module Gamefic
|
|
14
14
|
|
15
15
|
OVERWRITEABLE_CLASSES = [String, Numeric, Symbol].freeze
|
16
16
|
|
17
|
-
SWAPPABLE_VALUES = [true, false
|
17
|
+
SWAPPABLE_VALUES = [true, false].freeze
|
18
18
|
|
19
19
|
class << self
|
20
20
|
private
|
@@ -37,7 +37,7 @@ module Gamefic
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def overwriteable? cval, nval
|
40
|
-
return true if swappable?(cval, nval)
|
40
|
+
return true if cval.nil? || swappable?(cval, nval)
|
41
41
|
|
42
42
|
allowed = OVERWRITEABLE_CLASSES.find { |klass| cval.is_a?(klass) }
|
43
43
|
allowed && cval.is_a?(allowed)
|
data/lib/gamefic/subplot.rb
CHANGED
@@ -7,6 +7,8 @@ module Gamefic
|
|
7
7
|
# started and concluded at any time during the parent plot's runtime.
|
8
8
|
#
|
9
9
|
class Subplot < Narrative
|
10
|
+
extend Scriptable::PlotProxies
|
11
|
+
|
10
12
|
# @return [Hash]
|
11
13
|
attr_reader :config
|
12
14
|
|
@@ -22,7 +24,20 @@ module Gamefic
|
|
22
24
|
configure
|
23
25
|
@config.freeze
|
24
26
|
super()
|
25
|
-
|
27
|
+
@concluded = false
|
28
|
+
[introduce].flatten.each { |plyr| self.introduce plyr }
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.persist!
|
32
|
+
@persistent = true
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.persistent?
|
36
|
+
@persistent ||= false
|
37
|
+
end
|
38
|
+
|
39
|
+
def persistent?
|
40
|
+
self.class.persistent?
|
26
41
|
end
|
27
42
|
|
28
43
|
def included_blocks
|
@@ -41,6 +56,7 @@ module Gamefic
|
|
41
56
|
uncast plyr
|
42
57
|
end
|
43
58
|
entities.each { |ent| destroy ent }
|
59
|
+
@concluded = true
|
44
60
|
end
|
45
61
|
|
46
62
|
# Make an entity that persists in the subplot's parent plot.
|
@@ -69,6 +85,16 @@ module Gamefic
|
|
69
85
|
#
|
70
86
|
def configure; end
|
71
87
|
|
88
|
+
def concluding?
|
89
|
+
return super unless persistent?
|
90
|
+
|
91
|
+
@concluded
|
92
|
+
end
|
93
|
+
|
94
|
+
def introduce player
|
95
|
+
@concluded ? player : super
|
96
|
+
end
|
97
|
+
|
72
98
|
def inspect
|
73
99
|
"#<#{self.class}>"
|
74
100
|
end
|
data/lib/gamefic/version.rb
CHANGED
data/lib/gamefic.rb
CHANGED
@@ -17,6 +17,7 @@ require 'gamefic/command'
|
|
17
17
|
require 'gamefic/action'
|
18
18
|
require 'gamefic/props'
|
19
19
|
require 'gamefic/scene'
|
20
|
+
require 'gamefic/proxy'
|
20
21
|
require 'gamefic/scriptable'
|
21
22
|
require 'gamefic/block'
|
22
23
|
require 'gamefic/stage'
|
@@ -30,7 +31,6 @@ require 'gamefic/node'
|
|
30
31
|
require 'gamefic/describable'
|
31
32
|
require 'gamefic/messenger'
|
32
33
|
require 'gamefic/entity'
|
33
|
-
require 'gamefic/composer'
|
34
34
|
require 'gamefic/dispatcher'
|
35
35
|
require 'gamefic/active'
|
36
36
|
require 'gamefic/active/cue'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gamefic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fred Snyder
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-10-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: opal
|
@@ -138,7 +138,6 @@ files:
|
|
138
138
|
- lib/gamefic/callback.rb
|
139
139
|
- lib/gamefic/chapter.rb
|
140
140
|
- lib/gamefic/command.rb
|
141
|
-
- lib/gamefic/composer.rb
|
142
141
|
- lib/gamefic/core_ext/array.rb
|
143
142
|
- lib/gamefic/core_ext/string.rb
|
144
143
|
- lib/gamefic/describable.rb
|
@@ -156,6 +155,7 @@ files:
|
|
156
155
|
- lib/gamefic/props/output.rb
|
157
156
|
- lib/gamefic/props/pause.rb
|
158
157
|
- lib/gamefic/props/yes_or_no.rb
|
158
|
+
- lib/gamefic/proxy.rb
|
159
159
|
- lib/gamefic/query.rb
|
160
160
|
- lib/gamefic/query/base.rb
|
161
161
|
- lib/gamefic/query/general.rb
|
@@ -169,6 +169,12 @@ files:
|
|
169
169
|
- lib/gamefic/rulebook/hooks.rb
|
170
170
|
- lib/gamefic/rulebook/scenes.rb
|
171
171
|
- lib/gamefic/scanner.rb
|
172
|
+
- lib/gamefic/scanner/base.rb
|
173
|
+
- lib/gamefic/scanner/fuzzy.rb
|
174
|
+
- lib/gamefic/scanner/fuzzy_nesting.rb
|
175
|
+
- lib/gamefic/scanner/nesting.rb
|
176
|
+
- lib/gamefic/scanner/result.rb
|
177
|
+
- lib/gamefic/scanner/strict.rb
|
172
178
|
- lib/gamefic/scene.rb
|
173
179
|
- lib/gamefic/scene/activity.rb
|
174
180
|
- lib/gamefic/scene/conclusion.rb
|
@@ -179,6 +185,7 @@ files:
|
|
179
185
|
- lib/gamefic/scope.rb
|
180
186
|
- lib/gamefic/scope/base.rb
|
181
187
|
- lib/gamefic/scope/children.rb
|
188
|
+
- lib/gamefic/scope/descendants.rb
|
182
189
|
- lib/gamefic/scope/family.rb
|
183
190
|
- lib/gamefic/scope/myself.rb
|
184
191
|
- lib/gamefic/scope/parent.rb
|
@@ -187,7 +194,8 @@ files:
|
|
187
194
|
- lib/gamefic/scriptable/actions.rb
|
188
195
|
- lib/gamefic/scriptable/entities.rb
|
189
196
|
- lib/gamefic/scriptable/events.rb
|
190
|
-
- lib/gamefic/scriptable/
|
197
|
+
- lib/gamefic/scriptable/plot_proxies.rb
|
198
|
+
- lib/gamefic/scriptable/proxies.rb
|
191
199
|
- lib/gamefic/scriptable/queries.rb
|
192
200
|
- lib/gamefic/scriptable/scenes.rb
|
193
201
|
- lib/gamefic/snapshot.rb
|
data/lib/gamefic/composer.rb
DELETED
@@ -1,70 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Gamefic
|
4
|
-
# A function module for creating commands from expressions.
|
5
|
-
#
|
6
|
-
module Composer
|
7
|
-
# Create a command from the first expression that matches a response.
|
8
|
-
#
|
9
|
-
# @param actor [Actor]
|
10
|
-
# @param expressions [Array<Expression>]
|
11
|
-
# @return [Command]
|
12
|
-
def self.compose actor, expressions
|
13
|
-
%i[strict fuzzy].each do |method|
|
14
|
-
result = match_expressions_to_response actor, expressions, method
|
15
|
-
return result if result
|
16
|
-
end
|
17
|
-
Command.new(nil, [])
|
18
|
-
end
|
19
|
-
|
20
|
-
class << self
|
21
|
-
private
|
22
|
-
|
23
|
-
def match_expressions_to_response actor, expressions, method
|
24
|
-
expressions.each do |expression|
|
25
|
-
result = match_response_arguments actor, expression, method
|
26
|
-
return result if result
|
27
|
-
end
|
28
|
-
nil
|
29
|
-
end
|
30
|
-
|
31
|
-
def match_response_arguments actor, expression, method
|
32
|
-
actor.epic.responses_for(expression.verb).each do |response|
|
33
|
-
next unless response.queries.length >= expression.tokens.length
|
34
|
-
|
35
|
-
result = match_query_arguments(actor, expression, response, method)
|
36
|
-
return result if result
|
37
|
-
end
|
38
|
-
nil
|
39
|
-
end
|
40
|
-
|
41
|
-
def match_query_arguments actor, expression, response, method
|
42
|
-
remainder = response.verb ? '' : expression.verb.to_s
|
43
|
-
arguments = []
|
44
|
-
response.queries.each_with_index do |query, idx|
|
45
|
-
result = Scanner.send(method, query.select(actor), "#{remainder} #{expression.tokens[idx]}".strip)
|
46
|
-
break unless valid_result_from_query?(result, query)
|
47
|
-
|
48
|
-
if query.ambiguous?
|
49
|
-
arguments.push result.matched
|
50
|
-
else
|
51
|
-
arguments.push result.matched.first
|
52
|
-
end
|
53
|
-
remainder = result.remainder
|
54
|
-
end
|
55
|
-
|
56
|
-
return nil if arguments.length != response.queries.length || remainder != ''
|
57
|
-
|
58
|
-
Command.new(response.verb, arguments)
|
59
|
-
end
|
60
|
-
|
61
|
-
# @param result [Scanner::Result]
|
62
|
-
# @param query [Query::Base]
|
63
|
-
def valid_result_from_query? result, query
|
64
|
-
return false if result.matched.empty?
|
65
|
-
|
66
|
-
result.matched.length == 1 || query.ambiguous?
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
@@ -1,69 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Gamefic
|
4
|
-
module Scriptable
|
5
|
-
# Functions that provide proxies for referencing a narrative's entities
|
6
|
-
# from class-level scripts.
|
7
|
-
#
|
8
|
-
module Proxy
|
9
|
-
# The object that fetches a proxied entity.
|
10
|
-
#
|
11
|
-
class Agent
|
12
|
-
attr_reader :symbol
|
13
|
-
|
14
|
-
# @param symbol [Symbol, Integer]
|
15
|
-
def initialize symbol
|
16
|
-
@symbol = symbol
|
17
|
-
end
|
18
|
-
|
19
|
-
def fetch container
|
20
|
-
result = safe_fetch(container)
|
21
|
-
raise ArgumentError, "Unable to fetch entity from proxy agent symbol `#{symbol}`" unless result
|
22
|
-
|
23
|
-
result
|
24
|
-
end
|
25
|
-
|
26
|
-
private
|
27
|
-
|
28
|
-
def safe_fetch container
|
29
|
-
if symbol.to_s =~ /^\d+$/
|
30
|
-
Stage.run(container, symbol) { |sym| entities[sym] }
|
31
|
-
elsif symbol.to_s.start_with?('@')
|
32
|
-
Stage.run(container, symbol) { |sym| instance_variable_get(sym) }
|
33
|
-
else
|
34
|
-
Stage.run(container, symbol) { |sym| send(sym) }
|
35
|
-
end
|
36
|
-
rescue NoMethodError
|
37
|
-
nil
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
# Proxy a method or instance variable.
|
42
|
-
#
|
43
|
-
# @example
|
44
|
-
# proxy(:method_name)
|
45
|
-
# proxy(:@instance_variable_name)
|
46
|
-
#
|
47
|
-
# @param symbol [Symbol]
|
48
|
-
# @return [Agent]
|
49
|
-
def proxy symbol
|
50
|
-
Agent.new(symbol)
|
51
|
-
end
|
52
|
-
|
53
|
-
# @param object [Object]
|
54
|
-
# @return [Object]
|
55
|
-
def unproxy object
|
56
|
-
case object
|
57
|
-
when Agent
|
58
|
-
object.fetch self
|
59
|
-
when Array
|
60
|
-
object.map { |obj| unproxy obj }
|
61
|
-
when Hash
|
62
|
-
object.transform_values { |val| unproxy val }
|
63
|
-
else
|
64
|
-
object
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|