glimmer 1.0.7 → 1.1.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 +22 -0
- data/README.md +244 -257
- data/VERSION +1 -1
- data/glimmer.gemspec +36 -19
- data/lib/glimmer.rb +13 -1
- data/lib/glimmer/data_binding/model_binding.rb +37 -24
- data/lib/glimmer/data_binding/observable_array.rb +6 -5
- data/lib/glimmer/data_binding/observable_model.rb +3 -2
- data/lib/glimmer/data_binding/observer.rb +6 -2
- data/lib/glimmer/dsl/engine.rb +15 -13
- data/lib/glimmer/ext/module.rb +11 -0
- metadata +36 -15
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0
|
1
|
+
1.1.0
|
data/glimmer.gemspec
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
# Generated by jeweler
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in
|
3
|
+
# Instead, edit Jeweler::Tasks in rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: glimmer 1.0
|
5
|
+
# stub: glimmer 1.1.0 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "glimmer".freeze
|
9
|
-
s.version = "1.0
|
9
|
+
s.version = "1.1.0"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib".freeze]
|
13
13
|
s.authors = ["AndyMaleh".freeze]
|
14
|
-
s.date = "2021-
|
14
|
+
s.date = "2021-02-08"
|
15
15
|
s.description = "Glimmer is a Ruby DSL Framework consisting of a DSL Engine and an Observable/Observer/Data-Binding Library. Used in the Glimmer DSL for SWT (JRuby Desktop Development GUI Framework), the Glimmer DSL for Tk (Ruby Desktop Development GUI Library), the Glimmer DSL for Opal (Pure Ruby Web GUI and Auto-Webifier of Desktop Apps), the Glimmer DSL for XML (& HTML), and the Glimmer DSL for CSS.".freeze
|
16
16
|
s.email = "andy.am@gmail.com".freeze
|
17
17
|
s.extra_rdoc_files = [
|
@@ -41,33 +41,50 @@ Gem::Specification.new do |s|
|
|
41
41
|
"lib/glimmer/dsl/static_expression.rb",
|
42
42
|
"lib/glimmer/dsl/top_level_expression.rb",
|
43
43
|
"lib/glimmer/error.rb",
|
44
|
+
"lib/glimmer/ext/module.rb",
|
44
45
|
"lib/glimmer/invalid_keyword_error.rb"
|
45
46
|
]
|
46
47
|
s.homepage = "http://github.com/AndyObtiva/glimmer".freeze
|
47
48
|
s.licenses = ["MIT".freeze]
|
48
|
-
s.rubygems_version = "3.
|
49
|
+
s.rubygems_version = "3.0.6".freeze
|
49
50
|
s.summary = "Glimmer Ruby DSL Engine".freeze
|
50
51
|
|
51
52
|
if s.respond_to? :specification_version then
|
52
53
|
s.specification_version = 4
|
53
|
-
end
|
54
54
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
55
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
56
|
+
s.add_runtime_dependency(%q<array_include_methods>.freeze, [">= 1.0.4", "< 2.0.0"])
|
57
|
+
s.add_runtime_dependency(%q<facets>.freeze, [">= 3.1.0", "< 4.0.0"])
|
58
|
+
s.add_runtime_dependency(%q<concurrent-ruby>.freeze, [">= 1.1.7", "< 2.0.0"])
|
59
|
+
s.add_development_dependency(%q<rspec-mocks>.freeze, ["~> 3.5.0"])
|
60
|
+
s.add_development_dependency(%q<rspec>.freeze, ["~> 3.5.0"])
|
61
|
+
s.add_development_dependency(%q<puts_debuggerer>.freeze, ["~> 0.10.0"])
|
62
|
+
s.add_development_dependency(%q<rake>.freeze, [">= 10.1.0", "< 14.0.0"])
|
63
|
+
s.add_development_dependency(%q<jeweler>.freeze, [">= 2.0.0", "< 3.0.0"])
|
64
|
+
s.add_development_dependency(%q<rdoc>.freeze, [">= 6.2.1", "< 7.0.0"])
|
65
|
+
s.add_development_dependency(%q<coveralls>.freeze, [">= 0"])
|
66
|
+
s.add_development_dependency(%q<simplecov>.freeze, ["~> 0.16.1"])
|
67
|
+
s.add_development_dependency(%q<simplecov-lcov>.freeze, ["~> 0.7.0"])
|
68
|
+
s.add_development_dependency(%q<rake-tui>.freeze, [">= 0"])
|
69
|
+
else
|
70
|
+
s.add_dependency(%q<array_include_methods>.freeze, [">= 1.0.4", "< 2.0.0"])
|
71
|
+
s.add_dependency(%q<facets>.freeze, [">= 3.1.0", "< 4.0.0"])
|
72
|
+
s.add_dependency(%q<concurrent-ruby>.freeze, [">= 1.1.7", "< 2.0.0"])
|
73
|
+
s.add_dependency(%q<rspec-mocks>.freeze, ["~> 3.5.0"])
|
74
|
+
s.add_dependency(%q<rspec>.freeze, ["~> 3.5.0"])
|
75
|
+
s.add_dependency(%q<puts_debuggerer>.freeze, ["~> 0.10.0"])
|
76
|
+
s.add_dependency(%q<rake>.freeze, [">= 10.1.0", "< 14.0.0"])
|
77
|
+
s.add_dependency(%q<jeweler>.freeze, [">= 2.0.0", "< 3.0.0"])
|
78
|
+
s.add_dependency(%q<rdoc>.freeze, [">= 6.2.1", "< 7.0.0"])
|
79
|
+
s.add_dependency(%q<coveralls>.freeze, [">= 0"])
|
80
|
+
s.add_dependency(%q<simplecov>.freeze, ["~> 0.16.1"])
|
81
|
+
s.add_dependency(%q<simplecov-lcov>.freeze, ["~> 0.7.0"])
|
82
|
+
s.add_dependency(%q<rake-tui>.freeze, [">= 0"])
|
83
|
+
end
|
68
84
|
else
|
69
85
|
s.add_dependency(%q<array_include_methods>.freeze, [">= 1.0.4", "< 2.0.0"])
|
70
86
|
s.add_dependency(%q<facets>.freeze, [">= 3.1.0", "< 4.0.0"])
|
87
|
+
s.add_dependency(%q<concurrent-ruby>.freeze, [">= 1.1.7", "< 2.0.0"])
|
71
88
|
s.add_dependency(%q<rspec-mocks>.freeze, ["~> 3.5.0"])
|
72
89
|
s.add_dependency(%q<rspec>.freeze, ["~> 3.5.0"])
|
73
90
|
s.add_dependency(%q<puts_debuggerer>.freeze, ["~> 0.10.0"])
|
data/lib/glimmer.rb
CHANGED
@@ -22,10 +22,20 @@
|
|
22
22
|
require 'logger'
|
23
23
|
require 'set'
|
24
24
|
require 'array_include_methods'
|
25
|
+
if RUBY_ENGINE == 'opal'
|
26
|
+
module Concurrent
|
27
|
+
Array = ::Array
|
28
|
+
Hash = ::Hash
|
29
|
+
Set = ::Set
|
30
|
+
end
|
31
|
+
else
|
32
|
+
require 'concurrent-ruby'
|
33
|
+
end
|
25
34
|
|
26
35
|
$LOAD_PATH.unshift(File.expand_path('..', __FILE__))
|
27
36
|
|
28
37
|
require 'glimmer/config'
|
38
|
+
require 'glimmer/ext/module'
|
29
39
|
|
30
40
|
# Glimmer provides a JRuby Desktop UI DSL + Data-Binding functionality
|
31
41
|
#
|
@@ -56,7 +66,9 @@ module Glimmer
|
|
56
66
|
|
57
67
|
def method_missing(method_symbol, *args, &block)
|
58
68
|
# This if statement speeds up Glimmer in girb or whenever directly including on main object
|
59
|
-
is_excluded = Config.excluded_keyword_checkers.
|
69
|
+
is_excluded = Config.excluded_keyword_checkers.any? do |checker|
|
70
|
+
instance_exec(method_symbol, *args, &checker)
|
71
|
+
end
|
60
72
|
if is_excluded
|
61
73
|
Glimmer::Config.logger.debug "Glimmer excluded keyword: #{method_symbol}" if Glimmer::Config.log_excluded_keywords?
|
62
74
|
super(method_symbol, *args, &block)
|
@@ -33,7 +33,7 @@ module Glimmer
|
|
33
33
|
def initialize(base_model, property_name_expression, binding_options = nil)
|
34
34
|
@base_model = base_model
|
35
35
|
@property_name_expression = property_name_expression
|
36
|
-
@binding_options = binding_options ||
|
36
|
+
@binding_options = binding_options || Concurrent::Hash.new
|
37
37
|
if computed?
|
38
38
|
@computed_model_bindings = computed_by.map do |computed_by_property_expression|
|
39
39
|
self.class.new(base_model, computed_by_property_expression)
|
@@ -72,21 +72,6 @@ module Glimmer
|
|
72
72
|
nested_property? ? nested_property_name : property_name_expression
|
73
73
|
end
|
74
74
|
|
75
|
-
def convert_on_read(value)
|
76
|
-
apply_converter(@binding_options[:on_read], value)
|
77
|
-
end
|
78
|
-
|
79
|
-
def convert_on_write(value)
|
80
|
-
apply_converter(@binding_options[:on_write], value)
|
81
|
-
end
|
82
|
-
|
83
|
-
def apply_converter(converter, value)
|
84
|
-
return value if converter.nil?
|
85
|
-
return value.send(converter) if (converter.is_a?(String) || converter.is_a?(Symbol)) && value.respond_to?(converter)
|
86
|
-
return converter.call(value) if converter.respond_to?(:call, value)
|
87
|
-
raise Glimmer::Error, "Unsupported bind converter: #{converter.inspect}"
|
88
|
-
end
|
89
|
-
|
90
75
|
# All nested property names
|
91
76
|
# e.g. property name expression "address.state" gives ['address', 'state']
|
92
77
|
# If there are any indexed property names, this returns indexes as properties.
|
@@ -120,9 +105,9 @@ module Glimmer
|
|
120
105
|
end
|
121
106
|
|
122
107
|
def nested_property_observers_for(observer)
|
123
|
-
@nested_property_observers_collection ||=
|
108
|
+
@nested_property_observers_collection ||= Concurrent::Hash.new
|
124
109
|
unless @nested_property_observers_collection.has_key?(observer)
|
125
|
-
@nested_property_observers_collection[observer] = nested_property_names.reduce(
|
110
|
+
@nested_property_observers_collection[observer] = nested_property_names.reduce(Concurrent::Hash.new) do |output, property_name|
|
126
111
|
output.merge(
|
127
112
|
property_name => Observer.proc do |new_value|
|
128
113
|
# Ensure reattaching observers when a higher level nested property is updated (e.g. person.address changes reattaches person.address.street observer)
|
@@ -164,7 +149,7 @@ module Glimmer
|
|
164
149
|
end
|
165
150
|
|
166
151
|
def computed_observer_for(observer)
|
167
|
-
@computed_observer_collection ||=
|
152
|
+
@computed_observer_collection ||= Concurrent::Hash.new
|
168
153
|
unless @computed_observer_collection.has_key?(observer)
|
169
154
|
@computed_observer_collection[observer] = Observer.proc do |new_value|
|
170
155
|
observer.call(evaluate_property)
|
@@ -215,9 +200,12 @@ module Glimmer
|
|
215
200
|
def evaluate_property
|
216
201
|
value = nil
|
217
202
|
value = invoke_property_reader(model, property_name) unless model.nil?
|
218
|
-
|
203
|
+
apply_processor(@binding_options[:before_read], value)
|
204
|
+
converted_value = convert_on_read(value)
|
205
|
+
apply_processor(@binding_options[:after_read], converted_value)
|
206
|
+
converted_value
|
219
207
|
end
|
220
|
-
|
208
|
+
|
221
209
|
def evaluate_options_property
|
222
210
|
model.send(options_property_name) unless model.nil?
|
223
211
|
end
|
@@ -230,6 +218,29 @@ module Glimmer
|
|
230
218
|
property_expression.to_s.start_with?('[')
|
231
219
|
end
|
232
220
|
|
221
|
+
private
|
222
|
+
|
223
|
+
def convert_on_read(value)
|
224
|
+
apply_processor(@binding_options[:on_read], value)
|
225
|
+
end
|
226
|
+
|
227
|
+
def convert_on_write(value)
|
228
|
+
apply_processor(@binding_options[:on_write], value)
|
229
|
+
end
|
230
|
+
|
231
|
+
def apply_processor(processor, value)
|
232
|
+
return value if processor.nil?
|
233
|
+
return value.send(processor) if (processor.is_a?(String) || processor.is_a?(Symbol)) && value.respond_to?(processor)
|
234
|
+
return invoke_proc_with_exact_parameters(processor, value) if processor.respond_to?(:call)
|
235
|
+
raise Glimmer::Error, "Unsupported bind processor: #{processor.inspect}"
|
236
|
+
end
|
237
|
+
|
238
|
+
def invoke_proc_with_exact_parameters(proc_object, *args)
|
239
|
+
return if proc_object.nil?
|
240
|
+
args = args[0...proc_object.parameters.size]
|
241
|
+
proc_object.call(*args)
|
242
|
+
end
|
243
|
+
|
233
244
|
def invoke_property_reader(object, property_expression)
|
234
245
|
if property_indexed?(property_expression)
|
235
246
|
property_method = '[]'
|
@@ -243,14 +254,16 @@ module Glimmer
|
|
243
254
|
|
244
255
|
def invoke_property_writer(object, property_expression, value)
|
245
256
|
raise "Cannot invoke `#{property_expression}` because ModelBinding#binding_options[:read_only]=true" if @binding_options[:read_only]
|
246
|
-
|
257
|
+
apply_processor(@binding_options[:before_write], value)
|
258
|
+
converted_value = convert_on_write(value)
|
259
|
+
apply_processor(@binding_options[:after_write], converted_value)
|
247
260
|
if property_indexed?(property_expression)
|
248
261
|
property_method = '[]='
|
249
262
|
property_argument = property_expression[1...-2]
|
250
263
|
property_argument = property_argument.to_i if property_argument.match(/\d+/)
|
251
|
-
object.send(property_method, property_argument,
|
264
|
+
object.send(property_method, property_argument, converted_value)
|
252
265
|
else
|
253
|
-
object.send(property_expression,
|
266
|
+
object.send(property_expression, converted_value)
|
254
267
|
end
|
255
268
|
end
|
256
269
|
end
|
@@ -34,7 +34,7 @@ module Glimmer
|
|
34
34
|
element_properties = element_properties.flatten.compact.uniq
|
35
35
|
return observer if has_observer?(observer) && has_observer_element_properties?(observer, element_properties)
|
36
36
|
property_observer_list << observer
|
37
|
-
observer_element_properties[observer] = element_properties_for(observer) + Set.new(element_properties)
|
37
|
+
observer_element_properties[observer] = element_properties_for(observer) + Concurrent::Set.new(element_properties)
|
38
38
|
each { |element| add_element_observer(element, observer) }
|
39
39
|
observer
|
40
40
|
end
|
@@ -55,7 +55,7 @@ module Glimmer
|
|
55
55
|
element_properties = element_properties.flatten.compact.uniq
|
56
56
|
if !element_properties.empty?
|
57
57
|
old_element_properties = element_properties_for(observer)
|
58
|
-
observer_element_properties[observer] = element_properties_for(observer) - Set.new(element_properties)
|
58
|
+
observer_element_properties[observer] = element_properties_for(observer) - Concurrent::Set.new(element_properties)
|
59
59
|
each { |element| element_properties.each { |property| observer.unobserve(element, property) } }
|
60
60
|
end
|
61
61
|
if element_properties_for(observer).empty?
|
@@ -87,15 +87,15 @@ module Glimmer
|
|
87
87
|
end
|
88
88
|
|
89
89
|
def property_observer_list
|
90
|
-
@property_observer_list ||= Set.new
|
90
|
+
@property_observer_list ||= Concurrent::Set.new
|
91
91
|
end
|
92
92
|
|
93
93
|
def observer_element_properties
|
94
|
-
@observer_element_properties ||=
|
94
|
+
@observer_element_properties ||= Concurrent::Hash.new
|
95
95
|
end
|
96
96
|
|
97
97
|
def element_properties_for(observer)
|
98
|
-
observer_element_properties[observer] ||= Set.new
|
98
|
+
observer_element_properties[observer] ||= Concurrent::Set.new
|
99
99
|
end
|
100
100
|
|
101
101
|
def notify_observers
|
@@ -289,6 +289,7 @@ module Glimmer
|
|
289
289
|
return unless old_value.is_a?(ObservableModel) || old_value.is_a?(ObservableArray)
|
290
290
|
property_observer_list.each { |observer| observer.unregister_dependents_with_observable(observer.registration_for(self), old_value) }
|
291
291
|
end
|
292
|
+
alias deregister_dependent_observers unregister_dependent_observers
|
292
293
|
end
|
293
294
|
end
|
294
295
|
end
|
@@ -92,7 +92,7 @@ module Glimmer
|
|
92
92
|
end
|
93
93
|
|
94
94
|
def property_observer_list(property_name)
|
95
|
-
property_observer_hash[property_name.to_sym] = Set.new unless property_observer_hash[property_name.to_sym]
|
95
|
+
property_observer_hash[property_name.to_sym] = Concurrent::Set.new unless property_observer_hash[property_name.to_sym]
|
96
96
|
property_observer_hash[property_name.to_sym]
|
97
97
|
end
|
98
98
|
|
@@ -124,6 +124,7 @@ module Glimmer
|
|
124
124
|
return unless old_value.is_a?(ObservableModel) || old_value.is_a?(ObservableArray)
|
125
125
|
property_observer_list(property_name).each { |observer| observer.unregister_dependents_with_observable(observer.registration_for(self, property_name), old_value) }
|
126
126
|
end
|
127
|
+
alias deregister_dependent_observers unregister_dependent_observers
|
127
128
|
|
128
129
|
def ensure_array_object_observer(property_name, object, old_object = nil)
|
129
130
|
return unless object&.is_a?(Array)
|
@@ -137,7 +138,7 @@ module Glimmer
|
|
137
138
|
end
|
138
139
|
|
139
140
|
def array_object_observer_for(property_name)
|
140
|
-
@array_object_observers ||=
|
141
|
+
@array_object_observers ||= Concurrent::Hash.new
|
141
142
|
@array_object_observers[property_name] = ObservableModel::Notifier.new(self, property_name) unless @array_object_observers.has_key?(property_name)
|
142
143
|
@array_object_observers[property_name]
|
143
144
|
end
|
@@ -61,7 +61,7 @@ module Glimmer
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def registrations
|
64
|
-
@registrations ||= Set.new
|
64
|
+
@registrations ||= Concurrent::Set.new
|
65
65
|
end
|
66
66
|
|
67
67
|
def registration_for(observable, property = nil)
|
@@ -75,7 +75,7 @@ module Glimmer
|
|
75
75
|
end
|
76
76
|
|
77
77
|
def dependents_for(registration)
|
78
|
-
dependents[registration] ||= Set.new
|
78
|
+
dependents[registration] ||= Concurrent::Set.new
|
79
79
|
end
|
80
80
|
|
81
81
|
# registers observer in an observable on a property (optional)
|
@@ -110,6 +110,7 @@ module Glimmer
|
|
110
110
|
end
|
111
111
|
end
|
112
112
|
alias unobserve unregister
|
113
|
+
alias deregister unregister
|
113
114
|
|
114
115
|
def unregister_dependents_with_observable(registration, dependent_observable)
|
115
116
|
thedependents = dependents_for(registration).select do |thedependent|
|
@@ -117,12 +118,15 @@ module Glimmer
|
|
117
118
|
end
|
118
119
|
thedependents.each(&:unregister)
|
119
120
|
end
|
121
|
+
alias unobserve_dependents_with_observable unregister_dependents_with_observable
|
122
|
+
alias deregister_dependents_with_observable unregister_dependents_with_observable
|
120
123
|
|
121
124
|
# cleans up all registrations in observables
|
122
125
|
def unregister_all_observables
|
123
126
|
registrations.each(&:unregister)
|
124
127
|
end
|
125
128
|
alias unobserve_all_observables unregister_all_observables
|
129
|
+
alias deregister_all_observables unregister_all_observables
|
126
130
|
|
127
131
|
# add dependent observer to unregister when unregistering observer
|
128
132
|
def add_dependent(parent_to_dependent_hash)
|
data/lib/glimmer/dsl/engine.rb
CHANGED
@@ -28,7 +28,7 @@ module Glimmer
|
|
28
28
|
module DSL
|
29
29
|
# Glimmer DSL Engine
|
30
30
|
#
|
31
|
-
# Follows Interpreter
|
31
|
+
# Follows Interpreter, Chain of Responsibility, and Singleton Design Patterns
|
32
32
|
#
|
33
33
|
# When DSL engine interprets an expression, it attempts to handle
|
34
34
|
# with ordered expression array specified via `.expressions=` method.
|
@@ -37,10 +37,11 @@ module Glimmer
|
|
37
37
|
STATIC_EXPRESSION_METHOD_FACTORY = lambda do |keyword|
|
38
38
|
lambda do |*args, &block|
|
39
39
|
if Glimmer::DSL::Engine.no_dsls?
|
40
|
-
puts Glimmer::DSL::Engine::MESSAGE_NO_DSLS
|
40
|
+
puts Glimmer::DSL::Engine::MESSAGE_NO_DSLS # TODO consider switching to an error log statement
|
41
41
|
else
|
42
42
|
retrieved_static_expression = Glimmer::DSL::Engine.static_expressions[keyword][Glimmer::DSL::Engine.dsl]
|
43
|
-
|
43
|
+
# TODO consider replacing Glimmer::DSL::Engine.static_expressions[keyword].keys - Glimmer::DSL::Engine.disabled_dsls with Glimmer::DSL::Engine.enabled_static_expression_dsls(keyword)
|
44
|
+
static_expression_dsl = (Glimmer::DSL::Engine.static_expressions[keyword].keys - Glimmer::DSL::Engine.disabled_dsls).first
|
44
45
|
interpretation = nil
|
45
46
|
if retrieved_static_expression.nil? && Glimmer::DSL::Engine.dsl && (static_expression_dsl.nil? || !Glimmer::DSL::Engine.static_expressions[keyword][static_expression_dsl].is_a?(TopLevelExpression))
|
46
47
|
begin
|
@@ -55,8 +56,9 @@ module Glimmer
|
|
55
56
|
raise Glimmer::Error, "Unsupported keyword: #{keyword}" unless static_expression_dsl || retrieved_static_expression
|
56
57
|
Glimmer::DSL::Engine.dsl_stack.push(static_expression_dsl || Glimmer::DSL::Engine.dsl)
|
57
58
|
static_expression = Glimmer::DSL::Engine.static_expressions[keyword][Glimmer::DSL::Engine.dsl]
|
58
|
-
|
59
|
-
|
59
|
+
static_expression_can_interpret = nil
|
60
|
+
if static_expression.nil? || !(static_expression_can_interpret = static_expression.can_interpret?(Glimmer::DSL::Engine.parent, keyword, *args, &block))
|
61
|
+
raise Error, "Invalid use of Glimmer keyword #{keyword} with args #{args} under parent #{Glimmer::DSL::Engine.parent.inspect} with DSL #{Glimmer::DSL::Engine.dsl.inspect} and static expression #{static_expression.inspect} having can_interpret? as #{static_expression_can_interpret.inspect}"
|
60
62
|
else
|
61
63
|
Glimmer::Config.logger.info {"#{static_expression.class.name} will handle expression keyword #{keyword}"}
|
62
64
|
Glimmer::DSL::Engine.interpret_expression(static_expression, keyword, *args, &block)
|
@@ -86,7 +88,7 @@ module Glimmer
|
|
86
88
|
end
|
87
89
|
|
88
90
|
def disabled_dsls
|
89
|
-
@disabled_dsls ||=
|
91
|
+
@disabled_dsls ||= Concurrent::Array.new
|
90
92
|
end
|
91
93
|
|
92
94
|
def enabled_dsls=(dsl_names)
|
@@ -109,12 +111,12 @@ module Glimmer
|
|
109
111
|
|
110
112
|
# Dynamic expression chains of responsibility indexed by dsl
|
111
113
|
def dynamic_expression_chains_of_responsibility
|
112
|
-
@dynamic_expression_chains_of_responsibility ||=
|
114
|
+
@dynamic_expression_chains_of_responsibility ||= Concurrent::Hash.new
|
113
115
|
end
|
114
116
|
|
115
117
|
# Static expressions indexed by keyword and dsl
|
116
118
|
def static_expressions
|
117
|
-
@static_expressions ||=
|
119
|
+
@static_expressions ||= Concurrent::Hash.new
|
118
120
|
end
|
119
121
|
|
120
122
|
# Sets dynamic expression chains of responsibility. Useful for internal testing
|
@@ -147,7 +149,7 @@ module Glimmer
|
|
147
149
|
Glimmer::Config.logger.info {"Adding static expression: #{static_expression.class.name}"}
|
148
150
|
keyword = static_expression.class.keyword
|
149
151
|
static_expression_dsl = static_expression.class.dsl
|
150
|
-
static_expressions[keyword] ||=
|
152
|
+
static_expressions[keyword] ||= Concurrent::Hash.new
|
151
153
|
static_expressions[keyword][static_expression_dsl] = static_expression
|
152
154
|
Glimmer.send(:define_method, keyword, &STATIC_EXPRESSION_METHOD_FACTORY.call(keyword))
|
153
155
|
end
|
@@ -162,7 +164,7 @@ module Glimmer
|
|
162
164
|
|
163
165
|
# Interprets Glimmer dynamic DSL expression consisting of keyword, args, and block (e.g. shell(:no_resize) { ... })
|
164
166
|
def interpret(keyword, *args, &block)
|
165
|
-
return puts(MESSAGE_NO_DSLS) if no_dsls?
|
167
|
+
return puts(MESSAGE_NO_DSLS) if no_dsls? # TODO consider switching to an error log statement
|
166
168
|
keyword = keyword.to_s
|
167
169
|
dynamic_expression_dsl = (dynamic_expression_chains_of_responsibility.keys - disabled_dsls).first if dsl.nil?
|
168
170
|
# TODO consider pushing this code into interpret_expresion to provide hooks that work around it regardless of static vs dynamic
|
@@ -203,16 +205,16 @@ module Glimmer
|
|
203
205
|
def_delegator :parent_stack, :last, :parent
|
204
206
|
|
205
207
|
def parent_stack
|
206
|
-
parent_stacks[dsl] ||=
|
208
|
+
parent_stacks[dsl] ||= Concurrent::Array.new
|
207
209
|
end
|
208
210
|
|
209
211
|
def parent_stacks
|
210
|
-
@parent_stacks ||=
|
212
|
+
@parent_stacks ||= Concurrent::Hash.new
|
211
213
|
end
|
212
214
|
|
213
215
|
# Enables multiple DSLs to play well with each other when mixing together
|
214
216
|
def dsl_stack
|
215
|
-
@dsl_stack ||=
|
217
|
+
@dsl_stack ||= Concurrent::Array.new
|
216
218
|
end
|
217
219
|
end
|
218
220
|
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class Module
|
2
|
+
alias append_features_without_glimmer append_features
|
3
|
+
def append_features(mod)
|
4
|
+
if self == Glimmer && mod == Object
|
5
|
+
Glimmer::Config.logger.debug { 'Appending Glimmer to Singleton Class of main object (not appending to Object everywhere to avoid method pollution)' }
|
6
|
+
TOPLEVEL_BINDING.receiver.singleton_class.include(self)
|
7
|
+
else
|
8
|
+
append_features_without_glimmer(mod)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|