glimmer 0.10.0 → 1.0.0

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.
@@ -1,9 +1,29 @@
1
+ # Copyright (c) 2007-2020 Andy Maleh
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
1
22
  require 'glimmer/data_binding/observable'
2
23
  require 'glimmer/data_binding/observer'
3
24
 
4
25
  module Glimmer
5
26
  module DataBinding
6
- # TODO prefix utility methods with double-underscore
7
27
  module ObservableModel
8
28
  include Observable
9
29
 
@@ -17,6 +37,17 @@ module Glimmer
17
37
  @observable_model.notify_observers(@property_name)
18
38
  end
19
39
  end
40
+
41
+ PROPERTY_WRITER_FACTORY = lambda do |property_name|
42
+ property_writer_name = "#{property_name}="
43
+ lambda do |value|
44
+ old_value = self.send(property_name)
45
+ unregister_dependent_observers(property_name, old_value)
46
+ self.send("__original_#{property_writer_name}", value)
47
+ notify_observers(property_name)
48
+ ensure_array_object_observer(property_name, value, old_value)
49
+ end
50
+ end
20
51
 
21
52
  def add_observer(observer, property_name)
22
53
  return observer if has_observer?(observer, property_name)
@@ -34,7 +65,7 @@ module Glimmer
34
65
  end
35
66
 
36
67
  def has_observer_for_any_property?(observer)
37
- property_observer_hash.values.map(&:to_a).sum.include?(observer)
68
+ property_observer_hash.values.map(&:to_a).reduce(:+).include?(observer)
38
69
  end
39
70
 
40
71
  def property_observer_hash
@@ -47,9 +78,8 @@ module Glimmer
47
78
  end
48
79
 
49
80
  def notify_observers(property_name)
50
- property_observer_list(property_name).each {|observer| observer.call(send(property_name))}
81
+ property_observer_list(property_name).to_a.each { |observer| observer.call(send(property_name)) }
51
82
  end
52
- #TODO upon updating values, make sure dependent observers are cleared (not added as dependents here)
53
83
 
54
84
  def add_property_writer_observers(property_name)
55
85
  property_writer_name = "#{property_name}="
@@ -58,27 +88,22 @@ module Glimmer
58
88
  begin
59
89
  singleton_method("__original_#{property_writer_name}")
60
90
  rescue
61
- old_method = self.class.instance_method(property_writer_name) rescue self.method(property_writer_name)
62
- define_singleton_method("__original_#{property_writer_name}", old_method)
63
- define_singleton_method(property_writer_name) do |value|
64
- old_value = self.send(property_name)
65
- unregister_dependent_observers(property_name, old_value)
66
- self.send("__original_#{property_writer_name}", value)
67
- notify_observers(property_name)
68
- ensure_array_object_observer(property_name, value, old_value)
69
- end
91
+ define_singleton_method("__original_#{property_writer_name}", property_writer_method(property_writer_name))
92
+ define_singleton_method(property_writer_name, &PROPERTY_WRITER_FACTORY.call(property_name))
70
93
  end
71
94
  rescue => e
72
95
  #ignore writing if no property writer exists
73
96
  Glimmer::Config.logger.debug {"No need to observe property writer: #{property_writer_name}\n#{e.message}\n#{e.backtrace.join("\n")}"}
74
97
  end
98
+
99
+ def property_writer_method(property_writer_name)
100
+ self.class.instance_method(property_writer_name) rescue self.method(property_writer_name)
101
+ end
75
102
 
76
103
  def unregister_dependent_observers(property_name, old_value)
77
104
  # TODO look into optimizing this
78
105
  return unless old_value.is_a?(ObservableModel) || old_value.is_a?(ObservableArray)
79
- property_observer_list(property_name).each do |observer|
80
- observer.unregister_dependents_with_observable(observer.registration_for(self, property_name), old_value)
81
- end
106
+ property_observer_list(property_name).each { |observer| observer.unregister_dependents_with_observable(observer.registration_for(self, property_name), old_value) }
82
107
  end
83
108
 
84
109
  def ensure_array_object_observer(property_name, object, old_object = nil)
@@ -93,10 +118,8 @@ module Glimmer
93
118
  end
94
119
 
95
120
  def array_object_observer_for(property_name)
96
- @array_object_observers ||= {}
97
- unless @array_object_observers.has_key?(property_name)
98
- @array_object_observers[property_name] = ObservableModel::Notifier.new(self, property_name)
99
- end
121
+ @array_object_observers ||= {}
122
+ @array_object_observers[property_name] = ObservableModel::Notifier.new(self, property_name) unless @array_object_observers.has_key?(property_name)
100
123
  @array_object_observers[property_name]
101
124
  end
102
125
  end
@@ -1,3 +1,24 @@
1
+ # Copyright (c) 2007-2020 Andy Maleh
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
1
22
  require 'glimmer/error'
2
23
 
3
24
  module Glimmer
@@ -59,6 +80,7 @@ module Glimmer
59
80
  # registers observer in an observable on a property (optional)
60
81
  # observer maintains registration list to unregister later
61
82
  def register(observable, property = nil)
83
+ return if observable.nil?
62
84
  unless observable.is_a?(Observable)
63
85
  # TODO refactor code to be more smart/polymorphic/automated and honor open/closed principle
64
86
  if observable.is_a?(Array)
@@ -75,6 +97,7 @@ module Glimmer
75
97
  alias observe register
76
98
 
77
99
  def unregister(observable, property = nil)
100
+ return unless observable.is_a?(Observable)
78
101
  # TODO optimize performance in the future via indexing and/or making a registration official object/class
79
102
  observable.remove_observer(*[self, property].compact)
80
103
  registration = registration_for(observable, property)
@@ -90,16 +113,12 @@ module Glimmer
90
113
  thedependents = dependents_for(registration).select do |thedependent|
91
114
  thedependent.observable == dependent_observable
92
115
  end
93
- thedependents.each do |thedependent|
94
- thedependent.unregister
95
- end
116
+ thedependents.each(&:unregister)
96
117
  end
97
118
 
98
119
  # cleans up all registrations in observables
99
120
  def unregister_all_observables
100
- registrations.each do |registration|
101
- registration.unregister
102
- end
121
+ registrations.each(&:unregister)
103
122
  end
104
123
  alias unobserve_all_observables unregister_all_observables
105
124
 
@@ -1,3 +1,25 @@
1
+ # Copyright (c) 2007-2020 Andy Maleh
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ require 'forwardable'
1
23
  require 'facets/string/camelcase'
2
24
 
3
25
  require 'glimmer/dsl/expression_handler'
@@ -12,20 +34,42 @@ module Glimmer
12
34
  # with ordered expression array specified via `.expressions=` method.
13
35
  class Engine
14
36
  MESSAGE_NO_DSLS = "Glimmer has no DSLs configured. Add glimmer-dsl-swt gem or visit https://github.com/AndyObtiva/glimmer#multi-dsl-support for more details.\n"
37
+ STATIC_EXPRESSION_METHOD_FACTORY = lambda do |keyword|
38
+ lambda do |*args, &block|
39
+ if Glimmer::DSL::Engine.no_dsls?
40
+ puts Glimmer::DSL::Engine::MESSAGE_NO_DSLS
41
+ else
42
+ retrieved_static_expression = Glimmer::DSL::Engine.static_expressions[keyword][Glimmer::DSL::Engine.dsl]
43
+ static_expression_dsl = (Glimmer::DSL::Engine.static_expressions[keyword].keys - Glimmer::DSL::Engine.disabled_dsls).first if retrieved_static_expression.nil?
44
+ interpretation = nil
45
+ 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
+ begin
47
+ interpretation = Glimmer::DSL::Engine.interpret(keyword, *args, &block)
48
+ rescue => e
49
+ raise e if static_expression_dsl.nil? || !Glimmer::DSL::Engine.static_expressions[keyword][static_expression_dsl].is_a?(TopLevelExpression)
50
+ end
51
+ end
52
+ if interpretation
53
+ interpretation
54
+ else
55
+ raise Glimmer::Error, "Unsupported keyword: #{keyword}" unless static_expression_dsl || retrieved_static_expression
56
+ Glimmer::DSL::Engine.dsl_stack.push(static_expression_dsl || Glimmer::DSL::Engine.dsl)
57
+ static_expression = Glimmer::DSL::Engine.static_expressions[keyword][Glimmer::DSL::Engine.dsl]
58
+ if !static_expression.can_interpret?(Glimmer::DSL::Engine.parent, keyword, *args, &block)
59
+ raise Error, "Invalid use of Glimmer keyword #{keyword} with args #{args} under parent #{Glimmer::DSL::Engine.parent}"
60
+ else
61
+ Glimmer::Config.logger.info {"#{static_expression.class.name} will handle expression keyword #{keyword}"}
62
+ Glimmer::DSL::Engine.interpret_expression(static_expression, keyword, *args, &block)
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
15
68
 
16
69
  class << self
17
- def dsl=(dsl_name)
18
- dsl_name = dsl_name&.to_sym
19
- if dsl_name
20
- dsl_stack.push(dsl_name)
21
- else
22
- dsl_stack.clear
23
- end
24
- end
70
+ extend Forwardable
25
71
 
26
- def dsl
27
- dsl_stack.last
28
- end
72
+ def_delegator :dsl_stack, :last, :dsl
29
73
 
30
74
  def dsls
31
75
  static_expressions.values.map(&:keys).flatten.uniq
@@ -74,14 +118,10 @@ module Glimmer
74
118
  end
75
119
 
76
120
  # Sets dynamic expression chains of responsibility. Useful for internal testing
77
- def dynamic_expression_chains_of_responsibility=(chains)
78
- @dynamic_expression_chains_of_responsibility = chains
79
- end
121
+ attr_writer :dynamic_expression_chains_of_responsibility
80
122
 
81
123
  # Sets static expressions. Useful for internal testing
82
- def static_expressions=(expressions)
83
- @static_expressions = expressions
84
- end
124
+ attr_writer :static_expressions
85
125
 
86
126
  # Sets an ordered array of DSL expressions to support
87
127
  #
@@ -96,7 +136,7 @@ module Glimmer
96
136
  dynamic_expression_chains_of_responsibility[dsl] = expression_names.reverse.map do |expression_name|
97
137
  expression_class(dsl_namespace, expression_name).new
98
138
  end.reduce(nil) do |last_expresion_handler, expression|
99
- Glimmer::Config.logger.debug {"Adding dynamic expression: #{expression.class.name}"}
139
+ Glimmer::Config.logger.info {"Adding dynamic expression: #{expression.class.name}"}
100
140
  expression_handler = ExpressionHandler.new(expression)
101
141
  expression_handler.next = last_expresion_handler if last_expresion_handler
102
142
  expression_handler
@@ -104,43 +144,12 @@ module Glimmer
104
144
  end
105
145
 
106
146
  def add_static_expression(static_expression)
107
- Glimmer::Config.logger.debug {"Adding static expression: #{static_expression.class.name}"}
147
+ Glimmer::Config.logger.info {"Adding static expression: #{static_expression.class.name}"}
108
148
  keyword = static_expression.class.keyword
109
149
  static_expression_dsl = static_expression.class.dsl
110
150
  static_expressions[keyword] ||= {}
111
151
  static_expressions[keyword][static_expression_dsl] = static_expression
112
- Glimmer.send(:define_method, keyword) do |*args, &block|
113
- if Glimmer::DSL::Engine.no_dsls?
114
- puts Glimmer::DSL::Engine::MESSAGE_NO_DSLS
115
- else
116
- retrieved_static_expression = Glimmer::DSL::Engine.static_expressions[keyword][Glimmer::DSL::Engine.dsl]
117
- static_expression_dsl = (Glimmer::DSL::Engine.static_expressions[keyword].keys - Glimmer::DSL::Engine.disabled_dsls).first if retrieved_static_expression.nil?
118
- interpretation = nil
119
- 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))
120
- begin
121
- interpretation = Glimmer::DSL::Engine.interpret(keyword, *args, &block)
122
- rescue => e
123
- raise e if static_expression_dsl.nil? || !Glimmer::DSL::Engine.static_expressions[keyword][static_expression_dsl].is_a?(TopLevelExpression)
124
- end
125
- end
126
- if interpretation
127
- interpretation
128
- else
129
- raise Glimmer::Error, "Unsupported keyword: #{keyword}" unless static_expression_dsl || retrieved_static_expression
130
- Glimmer::DSL::Engine.dsl_stack.push(static_expression_dsl || Glimmer::DSL::Engine.dsl)
131
- static_expression = Glimmer::DSL::Engine.static_expressions[keyword][Glimmer::DSL::Engine.dsl]
132
- if !static_expression.can_interpret?(Glimmer::DSL::Engine.parent, keyword, *args, &block)
133
- raise Error, "Invalid use of Glimmer keyword #{keyword} with args #{args} under parent #{Glimmer::DSL::Engine.parent}"
134
- else
135
- Glimmer::Config.logger.debug {"#{static_expression.class.name} will handle expression keyword #{keyword}"}
136
- static_expression.interpret(Glimmer::DSL::Engine.parent, keyword, *args, &block).tap do |ui_object|
137
- Glimmer::DSL::Engine.add_content(ui_object, static_expression, &block) unless block.nil?
138
- Glimmer::DSL::Engine.dsl_stack.pop
139
- end
140
- end
141
- end
142
- end
143
- end
152
+ Glimmer.send(:define_method, keyword, &STATIC_EXPRESSION_METHOD_FACTORY.call(keyword))
144
153
  end
145
154
 
146
155
  def expression_class(dsl_namespace, expression_name)
@@ -152,16 +161,17 @@ module Glimmer
152
161
  end
153
162
 
154
163
  # Interprets Glimmer dynamic DSL expression consisting of keyword, args, and block (e.g. shell(:no_resize) { ... })
155
- def interpret(keyword, *args, &block)
156
- if no_dsls?
157
- puts MESSAGE_NO_DSLS
158
- return
159
- end
164
+ def interpret(keyword, *args, &block)
165
+ return puts(MESSAGE_NO_DSLS) if no_dsls?
160
166
  keyword = keyword.to_s
161
167
  dynamic_expression_dsl = (dynamic_expression_chains_of_responsibility.keys - disabled_dsls).first if dsl.nil?
162
168
  dsl_stack.push(dynamic_expression_dsl || dsl)
163
169
  expression = dynamic_expression_chains_of_responsibility[dsl].handle(parent, keyword, *args, &block)
164
- expression.interpret(parent, keyword, *args, &block).tap do |ui_object|
170
+ interpret_expression(expression, keyword, *args, &block)
171
+ end
172
+
173
+ def interpret_expression(expression, keyword, *args, &block)
174
+ expression.interpret(parent, keyword, *args, &block).tap do |ui_object|
165
175
  add_content(ui_object, expression, &block)
166
176
  dsl_stack.pop
167
177
  end
@@ -189,9 +199,7 @@ module Glimmer
189
199
  #
190
200
  # Parents are maintained in a stack while evaluating Glimmer DSL
191
201
  # to ensure properly ordered interpretation of DSL syntax
192
- def parent
193
- parent_stack.last
194
- end
202
+ def_delegator :parent_stack, :last, :parent
195
203
 
196
204
  def parent_stack
197
205
  parent_stacks[dsl] ||= []
@@ -1,3 +1,24 @@
1
+ # Copyright (c) 2007-2020 Andy Maleh
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
1
22
  require 'glimmer/error'
2
23
 
3
24
  module Glimmer
@@ -1,3 +1,24 @@
1
+ # Copyright (c) 2007-2020 Andy Maleh
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
1
22
  require 'glimmer/invalid_keyword_error'
2
23
 
3
24
  module Glimmer
@@ -23,9 +44,9 @@ module Glimmer
23
44
  # Otherwise, it forwards to the next handler configured via `#next=` method
24
45
  # If there is no handler next, then it raises an error
25
46
  def handle(parent, keyword, *args, &block)
26
- Glimmer::Config.logger.debug {"Attempting to handle #{keyword} with #{@expression.class.name.split(":").last}"}
47
+ Glimmer::Config.logger.info {"Attempting to handle #{keyword} with #{@expression.class.name.split(":").last}"}
27
48
  if @expression.can_interpret?(parent, keyword, *args, &block)
28
- Glimmer::Config.logger.debug {"#{@expression.class.name} will handle expression keyword #{keyword}"}
49
+ Glimmer::Config.logger.info {"#{@expression.class.name} will handle expression keyword #{keyword}"}
29
50
  return @expression
30
51
  elsif @next_expression_handler
31
52
  return @next_expression_handler.handle(parent, keyword, *args, &block)
@@ -34,7 +55,6 @@ module Glimmer
34
55
  message = "Glimmer keyword #{keyword} with args #{args} cannot be handled"
35
56
  message += " inside parent #{parent}" if parent
36
57
  message += "! Check the validity of the code."
37
- # Glimmer::Config.logger.error {message}
38
58
  raise InvalidKeywordError, message
39
59
  end
40
60
  end
@@ -1,3 +1,24 @@
1
+ # Copyright (c) 2007-2020 Andy Maleh
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
1
22
  require 'glimmer/error'
2
23
 
3
24
  module Glimmer