Class: Prefab::Context
- Inherits:
-
Object
- Object
- Prefab::Context
- Includes:
- Comparable
- Defined in:
- lib/prefab/context.rb
Defined Under Namespace
Classes: NamedContext
Constant Summary collapse
- BLANK_CONTEXT_NAME =
''
- THREAD_KEY =
:prefab_context
Instance Attribute Summary collapse
-
#contexts ⇒ Object
readonly
Returns the value of attribute contexts.
-
#id ⇒ Object
readonly
Returns the value of attribute id.
-
#parent ⇒ Object
readonly
Returns the value of attribute parent.
-
#seen_at ⇒ Object
readonly
Returns the value of attribute seen_at.
Class Method Summary collapse
- .clear_current ⇒ Object
- .current ⇒ Object
- .current=(context) ⇒ Object
- .default_context ⇒ Object
- .default_context=(context) ⇒ Object
- .global_context ⇒ Object
- .global_context=(context) ⇒ Object
- .join(hash: {}, parent: nil, id: :not_provided) ⇒ Object
- .merge_with_current(new_context_properties = {}) ⇒ Object
- .with_context(context) ⇒ Object
- .with_merged_context(context) ⇒ Object
Instance Method Summary collapse
- #<=>(other) ⇒ Object
- #blank? ⇒ Boolean
- #clear ⇒ Object
- #context(name) ⇒ Object
- #get(property_key, scope: nil) ⇒ Object
- #grouped_key ⇒ Object
-
#initialize(hash = {}) ⇒ Context
constructor
A new instance of Context.
- #merge_default(defaults) ⇒ Object
- #reportable_tree ⇒ Object
- #set(name, hash) ⇒ Object
- #slim_proto ⇒ Object
- #to_h ⇒ Object
- #to_proto(namespace) ⇒ Object
- #to_s ⇒ Object
-
#tree(depth = 0) ⇒ Object
Visualize a tree of the context up through its parents.
- #update_parent(parent) ⇒ Object
Constructor Details
#initialize(hash = {}) ⇒ Context
Returns a new instance of Context.
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/prefab/context.rb', line 95 def initialize(hash = {}) @contexts = {} @flattened = {} @seen_at = Time.now.utc.to_i if hash.is_a?(Hash) hash.map do |name, values| unless values.is_a?(Hash) warn "[DEPRECATION] Prefab contexts should be a hash with a key of the context name and a value of a hash." values = { name => values } name = BLANK_CONTEXT_NAME end @contexts[name.to_s] = NamedContext.new(name, values) values.each do |key, value| @flattened[name.to_s + '.' + key.to_s] = value end end else raise ArgumentError, 'must be a Hash' end end |
Instance Attribute Details
#contexts ⇒ Object (readonly)
Returns the value of attribute contexts.
34 35 36 |
# File 'lib/prefab/context.rb', line 34 def contexts @contexts end |
#id ⇒ Object (readonly)
Returns the value of attribute id.
34 35 36 |
# File 'lib/prefab/context.rb', line 34 def id @id end |
#parent ⇒ Object (readonly)
Returns the value of attribute parent.
34 35 36 |
# File 'lib/prefab/context.rb', line 34 def parent @parent end |
#seen_at ⇒ Object (readonly)
Returns the value of attribute seen_at.
34 35 36 |
# File 'lib/prefab/context.rb', line 34 def seen_at @seen_at end |
Class Method Details
.clear_current ⇒ Object
79 80 81 |
# File 'lib/prefab/context.rb', line 79 def clear_current Thread.current[THREAD_KEY] = nil end |
.current ⇒ Object
59 60 61 |
# File 'lib/prefab/context.rb', line 59 def current Thread.current[THREAD_KEY] ||= join(parent: default_context, id: :block) end |
.current=(context) ⇒ Object
55 56 57 |
# File 'lib/prefab/context.rb', line 55 def current=(context) Thread.current[THREAD_KEY] = join(hash: context || {}, parent: default_context, id: :block) end |
.default_context ⇒ Object
51 52 53 |
# File 'lib/prefab/context.rb', line 51 def default_context @default_context ||= join(parent: global_context, id: :default_context) end |
.default_context=(context) ⇒ Object
45 46 47 48 49 |
# File 'lib/prefab/context.rb', line 45 def default_context=(context) @default_context = join(hash: context, parent: global_context, id: :default_context) self.current.update_parent(@default_context) end |
.global_context ⇒ Object
41 42 43 |
# File 'lib/prefab/context.rb', line 41 def global_context @global_context ||= join(parent: nil, id: :global_context) end |
.global_context=(context) ⇒ Object
37 38 39 |
# File 'lib/prefab/context.rb', line 37 def global_context=(context) @global_context = join(hash: context, parent: nil, id: :global_context) end |
.join(hash: {}, parent: nil, id: :not_provided) ⇒ Object
88 89 90 91 92 93 |
# File 'lib/prefab/context.rb', line 88 def self.join(hash: {}, parent: nil, id: :not_provided) context = new(hash) context.update_parent(parent) context.instance_variable_set(:@id, id) context end |
.merge_with_current(new_context_properties = {}) ⇒ Object
83 84 85 |
# File 'lib/prefab/context.rb', line 83 def merge_with_current(new_context_properties = {}) new(current.to_h.merge(new_context_properties.to_h)) end |
.with_context(context) ⇒ Object
63 64 65 66 67 68 69 |
# File 'lib/prefab/context.rb', line 63 def with_context(context) old_context = Thread.current[THREAD_KEY] Thread.current[THREAD_KEY] = join(parent: default_context, hash: context, id: :block) yield ensure Thread.current[THREAD_KEY] = old_context end |
.with_merged_context(context) ⇒ Object
71 72 73 74 75 76 77 |
# File 'lib/prefab/context.rb', line 71 def with_merged_context(context) old_context = Thread.current[THREAD_KEY] Thread.current[THREAD_KEY] = join(parent: current, hash: context, id: :merged) yield ensure Thread.current[THREAD_KEY] = old_context end |
Instance Method Details
#<=>(other) ⇒ Object
240 241 242 243 244 245 246 |
# File 'lib/prefab/context.rb', line 240 def <=>(other) if other.is_a?(Prefab::Context) to_h <=> other.to_h else super end end |
#blank? ⇒ Boolean
122 123 124 |
# File 'lib/prefab/context.rb', line 122 def blank? contexts.empty? end |
#clear ⇒ Object
173 174 175 176 |
# File 'lib/prefab/context.rb', line 173 def clear @contexts = {} @flattened = {} end |
#context(name) ⇒ Object
178 179 180 |
# File 'lib/prefab/context.rb', line 178 def context(name) contexts[name.to_s] || NamedContext.new(name, {}) end |
#get(property_key, scope: nil) ⇒ Object
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/prefab/context.rb', line 133 def get(property_key, scope: nil) if !property_key.include?(".") property_key = BLANK_CONTEXT_NAME + '.' + property_key end if @flattened.key?(property_key) @flattened[property_key] else scope ||= property_key.split('.').first if @contexts[scope] # If the key is in the present scope, parent values should not be used. # We can consider the parent value clobbered by the present scope. nil else @parent&.get(property_key, scope: scope) end end end |
#grouped_key ⇒ Object
233 234 235 236 237 |
# File 'lib/prefab/context.rb', line 233 def grouped_key contexts.map do |_, context| context.key end.sort.join('|') end |
#merge_default(defaults) ⇒ Object
182 183 184 185 186 187 188 |
# File 'lib/prefab/context.rb', line 182 def merge_default(defaults) defaults.keys.each do |name| set(name, context(name).merge!(defaults[name])) end self end |
#reportable_tree ⇒ Object
190 191 192 193 194 195 196 197 198 199 200 |
# File 'lib/prefab/context.rb', line 190 def reportable_tree ctx = self reportables = [] while ctx reportables.unshift(ctx) ctx = ctx.parent end reportables end |
#set(name, hash) ⇒ Object
126 127 128 129 130 131 |
# File 'lib/prefab/context.rb', line 126 def set(name, hash) @contexts[name.to_s] = NamedContext.new(name, hash) hash.each do |key, value| @flattened[name.to_s + '.' + key.to_s] = value end end |
#slim_proto ⇒ Object
225 226 227 228 229 230 231 |
# File 'lib/prefab/context.rb', line 225 def slim_proto PrefabProto::ContextSet.new( contexts: contexts.map do |_, context| context.to_proto end ) end |
#to_h ⇒ Object
153 154 155 |
# File 'lib/prefab/context.rb', line 153 def to_h contexts.transform_values(&:to_h) end |
#to_proto(namespace) ⇒ Object
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 |
# File 'lib/prefab/context.rb', line 202 def to_proto(namespace) prefab_context = { 'current-time' => ConfigValueWrapper.wrap(Prefab::TimeHelpers.now_in_ms) } prefab_context['namespace'] = ConfigValueWrapper.wrap(namespace) if namespace&.length&.positive? reportable_contexts = {} reportable_tree.each do |ctx| ctx.contexts.each do |name, context| reportable_contexts[name] = context end end PrefabProto::ContextSet.new( contexts: reportable_contexts.map do |name, context| context.to_proto end.concat([PrefabProto::Context.new(type: 'prefab', values: prefab_context)]) ) end |
#to_s ⇒ Object
157 158 159 |
# File 'lib/prefab/context.rb', line 157 def to_s "#<Prefab::Context:#{object_id} id=#{@id} #{to_h}>" end |
#tree(depth = 0) ⇒ Object
Visualize a tree of the context up through its parents
example:
| jit: “user”=>{“name”=>“Frank”} |– block: “clock”=>{“timezone”=>“PST”} |—- default_context: “prefab-api-key”=>{“user-id”=>123} |—— global_context: “speed”=>“2.4GHz”, “clock”=>“timezone”=>“UTC”}
169 170 171 |
# File 'lib/prefab/context.rb', line 169 def tree(depth = 0) "|" + ("-" * depth) + " #{id}: #{(" " * (30 - id.to_s.length - depth ))}#{to_h}\n" + (@parent&.tree(depth + 2) || '') end |
#update_parent(parent) ⇒ Object
118 119 120 |
# File 'lib/prefab/context.rb', line 118 def update_parent(parent) @parent = parent end |