glimmer 2.4.0 → 2.5.3
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/CHANGELOG.md +23 -0
 - data/README.md +229 -139
 - data/VERSION +1 -1
 - data/glimmer.gemspec +90 -89
 - data/lib/glimmer/data_binding/model_binding.rb +19 -8
 - data/lib/glimmer/data_binding/observable_array.rb +21 -15
 - data/lib/glimmer/data_binding/observable_hash.rb +3 -61
 - data/lib/glimmer/data_binding/observable_hashable.rb +75 -0
 - data/lib/glimmer/data_binding/observable_model.rb +27 -35
 - data/lib/glimmer/data_binding/observer.rb +16 -14
 - metadata +10 -8
 
| 
         @@ -19,13 +19,13 @@ 
     | 
|
| 
       19 
19 
     | 
    
         
             
            # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
         
     | 
| 
       20 
20 
     | 
    
         
             
            # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
         
     | 
| 
       21 
21 
     | 
    
         | 
| 
       22 
     | 
    
         
            -
            require 'glimmer/data_binding/ 
     | 
| 
      
 22 
     | 
    
         
            +
            require 'glimmer/data_binding/observable_hashable'
         
     | 
| 
       23 
23 
     | 
    
         
             
            require 'glimmer/data_binding/observer'
         
     | 
| 
       24 
24 
     | 
    
         | 
| 
       25 
25 
     | 
    
         
             
            module Glimmer
         
     | 
| 
       26 
26 
     | 
    
         
             
              module DataBinding
         
     | 
| 
       27 
27 
     | 
    
         
             
                module ObservableModel
         
     | 
| 
       28 
     | 
    
         
            -
                  include  
     | 
| 
      
 28 
     | 
    
         
            +
                  include ObservableHashable
         
     | 
| 
       29 
29 
     | 
    
         | 
| 
       30 
30 
     | 
    
         
             
                  class Notifier
         
     | 
| 
       31 
31 
     | 
    
         
             
                    include Observer
         
     | 
| 
         @@ -40,25 +40,26 @@ module Glimmer 
     | 
|
| 
       40 
40 
     | 
    
         
             
                    end
         
     | 
| 
       41 
41 
     | 
    
         
             
                  end
         
     | 
| 
       42 
42 
     | 
    
         | 
| 
       43 
     | 
    
         
            -
                  PROPERTY_WRITER_FACTORY = lambda do |property_name|
         
     | 
| 
      
 43 
     | 
    
         
            +
                  PROPERTY_WRITER_FACTORY = lambda do |property_name, options|
         
     | 
| 
       44 
44 
     | 
    
         
             
                    property_writer_name = "#{property_name}="
         
     | 
| 
       45 
45 
     | 
    
         
             
                    lambda do |value|
         
     | 
| 
       46 
46 
     | 
    
         
             
                      old_value = self.send(property_name)
         
     | 
| 
       47 
     | 
    
         
            -
                      unregister_dependent_observers(property_name, old_value) # remove dependent observers previously installed in ensure_array_object_observer 
     | 
| 
      
 47 
     | 
    
         
            +
                      unregister_dependent_observers(property_name, old_value) # remove dependent observers previously installed in ensure_array_object_observer
         
     | 
| 
       48 
48 
     | 
    
         
             
                      self.send("__original__#{property_writer_name}", value)
         
     | 
| 
       49 
49 
     | 
    
         
             
                      notify_observers(property_name)
         
     | 
| 
       50 
     | 
    
         
            -
                      ensure_array_object_observer(property_name, value, old_value)
         
     | 
| 
       51 
     | 
    
         
            -
                      ensure_hash_object_observer(property_name, value, old_value)
         
     | 
| 
      
 50 
     | 
    
         
            +
                      ensure_array_object_observer(property_name, value, old_value, options)
         
     | 
| 
       52 
51 
     | 
    
         
             
                    end
         
     | 
| 
       53 
52 
     | 
    
         
             
                  end
         
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
      
 53 
     | 
    
         
            +
                  
         
     | 
| 
       55 
54 
     | 
    
         
             
                  def add_observer(observer, property_name, options = {})
         
     | 
| 
       56 
55 
     | 
    
         
             
                    return observer if has_observer?(observer, property_name)
         
     | 
| 
       57 
56 
     | 
    
         
             
                    property_observer_list(property_name) << observer
         
     | 
| 
       58 
57 
     | 
    
         
             
                    add_property_writer_observers(property_name, options)
         
     | 
| 
      
 58 
     | 
    
         
            +
                    open_struct_loaded = !!::OpenStruct rescue false
         
     | 
| 
      
 59 
     | 
    
         
            +
                    add_key_writer_observer(property_name, options) if is_a?(Struct) || (open_struct_loaded && is_a?(OpenStruct))
         
     | 
| 
       59 
60 
     | 
    
         
             
                    observer
         
     | 
| 
       60 
61 
     | 
    
         
             
                  end
         
     | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
      
 62 
     | 
    
         
            +
                  
         
     | 
| 
       62 
63 
     | 
    
         
             
                  def remove_observer(observer, property_name, options = {})
         
     | 
| 
       63 
64 
     | 
    
         
             
                    if has_observer?(observer, property_name)
         
     | 
| 
       64 
65 
     | 
    
         
             
                      property_observer_list(property_name).delete(observer)
         
     | 
| 
         @@ -67,10 +68,11 @@ module Glimmer 
     | 
|
| 
       67 
68 
     | 
    
         
             
                  end
         
     | 
| 
       68 
69 
     | 
    
         | 
| 
       69 
70 
     | 
    
         
             
                  def remove_observers(property_name)
         
     | 
| 
       70 
     | 
    
         
            -
                     
     | 
| 
      
 71 
     | 
    
         
            +
                    property_key = property_name&.to_sym
         
     | 
| 
      
 72 
     | 
    
         
            +
                    property_observer_hash[property_key].each do |observer|
         
     | 
| 
       71 
73 
     | 
    
         
             
                      remove_observer(observer, property_name)
         
     | 
| 
       72 
74 
     | 
    
         
             
                    end
         
     | 
| 
       73 
     | 
    
         
            -
                    property_observer_hash.delete( 
     | 
| 
      
 75 
     | 
    
         
            +
                    property_observer_hash.delete(property_key)
         
     | 
| 
       74 
76 
     | 
    
         
             
                  end
         
     | 
| 
       75 
77 
     | 
    
         | 
| 
       76 
78 
     | 
    
         
             
                  def remove_all_observers
         
     | 
| 
         @@ -91,28 +93,36 @@ module Glimmer 
     | 
|
| 
       91 
93 
     | 
    
         
             
                  end
         
     | 
| 
       92 
94 
     | 
    
         | 
| 
       93 
95 
     | 
    
         
             
                  def property_observer_hash
         
     | 
| 
       94 
     | 
    
         
            -
                    @property_observers ||= Hash.new
         
     | 
| 
      
 96 
     | 
    
         
            +
                    @property_observers ||= Concurrent::Hash.new
         
     | 
| 
       95 
97 
     | 
    
         
             
                  end
         
     | 
| 
       96 
98 
     | 
    
         | 
| 
       97 
99 
     | 
    
         
             
                  def property_observer_list(property_name)
         
     | 
| 
       98 
     | 
    
         
            -
                     
     | 
| 
       99 
     | 
    
         
            -
                    property_observer_hash[ 
     | 
| 
      
 100 
     | 
    
         
            +
                    property_key = property_name&.to_sym
         
     | 
| 
      
 101 
     | 
    
         
            +
                    property_observer_hash[property_key] = Concurrent::Set.new unless property_observer_hash[property_key]
         
     | 
| 
      
 102 
     | 
    
         
            +
                    property_observer_hash[property_key]
         
     | 
| 
       100 
103 
     | 
    
         
             
                  end
         
     | 
| 
      
 104 
     | 
    
         
            +
                  alias key_observer_list property_observer_list
         
     | 
| 
      
 105 
     | 
    
         
            +
                  
         
     | 
| 
      
 106 
     | 
    
         
            +
                  def all_property_observer_list
         
     | 
| 
      
 107 
     | 
    
         
            +
                    property_observer_list(nil)
         
     | 
| 
      
 108 
     | 
    
         
            +
                  end
         
     | 
| 
      
 109 
     | 
    
         
            +
                  alias all_key_observer_list all_property_observer_list
         
     | 
| 
       101 
110 
     | 
    
         | 
| 
       102 
111 
     | 
    
         
             
                  def notify_observers(property_name)
         
     | 
| 
       103 
112 
     | 
    
         
             
                    property_observer_list(property_name).to_a.each { |observer| observer.call(send(property_name)) }
         
     | 
| 
       104 
113 
     | 
    
         
             
                  end
         
     | 
| 
       105 
     | 
    
         
            -
             
     | 
| 
      
 114 
     | 
    
         
            +
                  
         
     | 
| 
       106 
115 
     | 
    
         
             
                  def add_property_writer_observers(property_name, options)
         
     | 
| 
       107 
116 
     | 
    
         
             
                    property_writer_name = "#{property_name}="
         
     | 
| 
       108 
117 
     | 
    
         
             
                    method(property_writer_name)
         
     | 
| 
       109 
118 
     | 
    
         
             
                    ensure_array_object_observer(property_name, send(property_name), nil, options)
         
     | 
| 
       110 
     | 
    
         
            -
                    ensure_hash_object_observer(property_name, send(property_name), nil, options)
         
     | 
| 
       111 
119 
     | 
    
         
             
                    begin
         
     | 
| 
       112 
120 
     | 
    
         
             
                      method("__original__#{property_writer_name}")
         
     | 
| 
       113 
121 
     | 
    
         
             
                    rescue
         
     | 
| 
       114 
122 
     | 
    
         
             
                      define_singleton_method("__original__#{property_writer_name}", property_writer_method(property_writer_name))
         
     | 
| 
       115 
     | 
    
         
            -
                       
     | 
| 
      
 123 
     | 
    
         
            +
                      # Note the limitation that the first observe call options apply to all subsequent observations meaning even if unobserve was called, options do not change from initial ones
         
     | 
| 
      
 124 
     | 
    
         
            +
                      # It is good enough for now. If there is a need to address this in the future, this is where to start the work
         
     | 
| 
      
 125 
     | 
    
         
            +
                      define_singleton_method(property_writer_name, &PROPERTY_WRITER_FACTORY.call(property_name, options))
         
     | 
| 
       116 
126 
     | 
    
         
             
                    end
         
     | 
| 
       117 
127 
     | 
    
         
             
                  rescue => e
         
     | 
| 
       118 
128 
     | 
    
         
             
                    #ignore writing if no property writer exists
         
     | 
| 
         @@ -130,7 +140,7 @@ module Glimmer 
     | 
|
| 
       130 
140 
     | 
    
         
             
                  end
         
     | 
| 
       131 
141 
     | 
    
         
             
                  alias deregister_dependent_observers unregister_dependent_observers
         
     | 
| 
       132 
142 
     | 
    
         | 
| 
       133 
     | 
    
         
            -
                  def ensure_array_object_observer(property_name, object, old_object = nil, options =  
     | 
| 
      
 143 
     | 
    
         
            +
                  def ensure_array_object_observer(property_name, object, old_object = nil, options = nil)
         
     | 
| 
       134 
144 
     | 
    
         
             
                    options ||= {}
         
     | 
| 
       135 
145 
     | 
    
         
             
                    return unless object&.is_a?(Array)
         
     | 
| 
       136 
146 
     | 
    
         
             
                    array_object_observer = array_object_observer_for(property_name)
         
     | 
| 
         @@ -147,24 +157,6 @@ module Glimmer 
     | 
|
| 
       147 
157 
     | 
    
         
             
                    @array_object_observers[property_name] = Notifier.new(self, property_name) unless @array_object_observers.has_key?(property_name)
         
     | 
| 
       148 
158 
     | 
    
         
             
                    @array_object_observers[property_name]
         
     | 
| 
       149 
159 
     | 
    
         
             
                  end
         
     | 
| 
       150 
     | 
    
         
            -
                  
         
     | 
| 
       151 
     | 
    
         
            -
                  def ensure_hash_object_observer(property_name, object, old_object = nil, options)
         
     | 
| 
       152 
     | 
    
         
            -
                    options ||= {}
         
     | 
| 
       153 
     | 
    
         
            -
                    return unless object&.is_a?(Hash)
         
     | 
| 
       154 
     | 
    
         
            -
                    hash_object_observer = hash_object_observer_for(property_name)
         
     | 
| 
       155 
     | 
    
         
            -
                    hash_observer_registration = hash_object_observer.observe(object, options)
         
     | 
| 
       156 
     | 
    
         
            -
                    property_observer_list(property_name).each do |observer|
         
     | 
| 
       157 
     | 
    
         
            -
                      my_registration = observer.registration_for(self, property_name) # TODO eliminate repetition
         
     | 
| 
       158 
     | 
    
         
            -
                      observer.add_dependent(my_registration => hash_observer_registration)
         
     | 
| 
       159 
     | 
    
         
            -
                    end
         
     | 
| 
       160 
     | 
    
         
            -
                    hash_object_observer_for(property_name).unregister(old_object) if old_object.is_a?(ObservableHash)
         
     | 
| 
       161 
     | 
    
         
            -
                  end
         
     | 
| 
       162 
     | 
    
         
            -
             
     | 
| 
       163 
     | 
    
         
            -
                  def hash_object_observer_for(property_name)
         
     | 
| 
       164 
     | 
    
         
            -
                    @hash_object_observers ||= Concurrent::Hash.new
         
     | 
| 
       165 
     | 
    
         
            -
                    @hash_object_observers[property_name] = Notifier.new(self, property_name) unless @hash_object_observers.has_key?(property_name)
         
     | 
| 
       166 
     | 
    
         
            -
                    @hash_object_observers[property_name]
         
     | 
| 
       167 
     | 
    
         
            -
                  end
         
     | 
| 
       168 
160 
     | 
    
         
             
                end
         
     | 
| 
       169 
161 
     | 
    
         
             
              end
         
     | 
| 
       170 
162 
     | 
    
         
             
            end
         
     | 
| 
         @@ -47,11 +47,11 @@ module Glimmer 
     | 
|
| 
       47 
47 
     | 
    
         
             
                  end
         
     | 
| 
       48 
48 
     | 
    
         | 
| 
       49 
49 
     | 
    
         
             
                  class Registration < Struct.new(:observer, :observable, :args, keyword_init: true)
         
     | 
| 
       50 
     | 
    
         
            -
                    def  
     | 
| 
      
 50 
     | 
    
         
            +
                    def deregister
         
     | 
| 
       51 
51 
     | 
    
         
             
                      observer.unobserve(observable, *args)
         
     | 
| 
       52 
52 
     | 
    
         
             
                    end
         
     | 
| 
       53 
     | 
    
         
            -
                    alias  
     | 
| 
       54 
     | 
    
         
            -
                    alias deregister 
     | 
| 
      
 53 
     | 
    
         
            +
                    alias unregister deregister
         
     | 
| 
      
 54 
     | 
    
         
            +
                    alias unobserve deregister
         
     | 
| 
       55 
55 
     | 
    
         
             
                  end
         
     | 
| 
       56 
56 
     | 
    
         | 
| 
       57 
57 
     | 
    
         
             
                  class << self
         
     | 
| 
         @@ -82,8 +82,10 @@ module Glimmer 
     | 
|
| 
       82 
82 
     | 
    
         | 
| 
       83 
83 
     | 
    
         
             
                  # registers observer in an observable on args usually containing a property and options (optional)
         
     | 
| 
       84 
84 
     | 
    
         
             
                  # observer maintains registration list to unregister later
         
     | 
| 
       85 
     | 
    
         
            -
                  def  
     | 
| 
      
 85 
     | 
    
         
            +
                  def observe(observable, *args)
         
     | 
| 
      
 86 
     | 
    
         
            +
                    options = args.last.is_a?(Hash) ? args.last : {}
         
     | 
| 
       86 
87 
     | 
    
         
             
                    return if observable.nil?
         
     | 
| 
      
 88 
     | 
    
         
            +
                    return if options[:ignore_frozen] && observable.frozen?
         
     | 
| 
       87 
89 
     | 
    
         
             
                    unless observable.is_a?(Observable)
         
     | 
| 
       88 
90 
     | 
    
         
             
                      # TODO refactor code to be more smart/polymorphic/automated and honor open/closed principle (e.g. for SomeClass, search if there is ObservableSomeClass)
         
     | 
| 
       89 
91 
     | 
    
         
             
                      if observable.is_a?(Array)
         
     | 
| 
         @@ -98,9 +100,9 @@ module Glimmer 
     | 
|
| 
       98 
100 
     | 
    
         
             
                    observable.add_observer(self, *args)
         
     | 
| 
       99 
101 
     | 
    
         
             
                    ensure_registration_for!(observable, *args)
         
     | 
| 
       100 
102 
     | 
    
         
             
                  end
         
     | 
| 
       101 
     | 
    
         
            -
                  alias observe 
     | 
| 
      
 103 
     | 
    
         
            +
                  alias register observe
         
     | 
| 
       102 
104 
     | 
    
         | 
| 
       103 
     | 
    
         
            -
                  def  
     | 
| 
      
 105 
     | 
    
         
            +
                  def unobserve(observable, *args)
         
     | 
| 
       104 
106 
     | 
    
         
             
                    return unless observable.is_a?(Observable)
         
     | 
| 
       105 
107 
     | 
    
         
             
                    args = compact_args(args)
         
     | 
| 
       106 
108 
     | 
    
         
             
                    registration = registration_for(observable, *args)
         
     | 
| 
         @@ -113,27 +115,27 @@ module Glimmer 
     | 
|
| 
       113 
115 
     | 
    
         
             
                      observable.remove_observer(self, *args)
         
     | 
| 
       114 
116 
     | 
    
         
             
                    end
         
     | 
| 
       115 
117 
     | 
    
         
             
                  end
         
     | 
| 
       116 
     | 
    
         
            -
                  alias unobserve 
     | 
| 
       117 
     | 
    
         
            -
                  alias deregister  
     | 
| 
      
 118 
     | 
    
         
            +
                  alias unregister unobserve
         
     | 
| 
      
 119 
     | 
    
         
            +
                  alias deregister unobserve
         
     | 
| 
       118 
120 
     | 
    
         | 
| 
       119 
     | 
    
         
            -
                  def  
     | 
| 
      
 121 
     | 
    
         
            +
                  def unobserve_dependents_with_observable(registration, dependent_observable)
         
     | 
| 
       120 
122 
     | 
    
         
             
                    thedependents = dependents_for(registration).select do |thedependent|
         
     | 
| 
       121 
123 
     | 
    
         
             
                      thedependent.observable == dependent_observable
         
     | 
| 
       122 
124 
     | 
    
         
             
                    end
         
     | 
| 
       123 
125 
     | 
    
         
             
                    thedependents.each(&:deregister)
         
     | 
| 
       124 
126 
     | 
    
         
             
                  end
         
     | 
| 
       125 
     | 
    
         
            -
                  alias unobserve_dependents_with_observable 
     | 
| 
       126 
     | 
    
         
            -
                  alias deregister_dependents_with_observable  
     | 
| 
      
 127 
     | 
    
         
            +
                  alias unregister_dependents_with_observable unobserve_dependents_with_observable
         
     | 
| 
      
 128 
     | 
    
         
            +
                  alias deregister_dependents_with_observable unobserve_dependents_with_observable
         
     | 
| 
       127 
129 
     | 
    
         | 
| 
       128 
130 
     | 
    
         
             
                  # cleans up all registrations in observables
         
     | 
| 
       129 
     | 
    
         
            -
                  def  
     | 
| 
      
 131 
     | 
    
         
            +
                  def unobserve_all_observables
         
     | 
| 
       130 
132 
     | 
    
         
             
                    registrations.values.dup.each do |registration|
         
     | 
| 
       131 
133 
     | 
    
         
             
                      registration.deregister
         
     | 
| 
       132 
134 
     | 
    
         
             
                      registrations.delete([registration.observable.object_id, registration.args])
         
     | 
| 
       133 
135 
     | 
    
         
             
                    end
         
     | 
| 
       134 
136 
     | 
    
         
             
                  end
         
     | 
| 
       135 
     | 
    
         
            -
                  alias unobserve_all_observables 
     | 
| 
       136 
     | 
    
         
            -
                  alias deregister_all_observables  
     | 
| 
      
 137 
     | 
    
         
            +
                  alias unregister_all_observables unobserve_all_observables
         
     | 
| 
      
 138 
     | 
    
         
            +
                  alias deregister_all_observables unobserve_all_observables
         
     | 
| 
       137 
139 
     | 
    
         | 
| 
       138 
140 
     | 
    
         
             
                  # add dependent observer to unregister when unregistering observer
         
     | 
| 
       139 
141 
     | 
    
         
             
                  def add_dependent(parent_to_dependent_hash)
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,14 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: glimmer
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 2. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 2.5.3
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - AndyMaleh
         
     | 
| 
       8 
8 
     | 
    
         
             
            autorequire:
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date: 2021- 
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2021-12-07 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: array_include_methods
         
     | 
| 
         @@ -192,23 +192,24 @@ dependencies: 
     | 
|
| 
       192 
192 
     | 
    
         
             
              name: rake-tui
         
     | 
| 
       193 
193 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
       194 
194 
     | 
    
         
             
                requirements:
         
     | 
| 
       195 
     | 
    
         
            -
                - - " 
     | 
| 
      
 195 
     | 
    
         
            +
                - - ">"
         
     | 
| 
       196 
196 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       197 
197 
     | 
    
         
             
                    version: '0'
         
     | 
| 
       198 
198 
     | 
    
         
             
              type: :development
         
     | 
| 
       199 
199 
     | 
    
         
             
              prerelease: false
         
     | 
| 
       200 
200 
     | 
    
         
             
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
       201 
201 
     | 
    
         
             
                requirements:
         
     | 
| 
       202 
     | 
    
         
            -
                - - " 
     | 
| 
      
 202 
     | 
    
         
            +
                - - ">"
         
     | 
| 
       203 
203 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       204 
204 
     | 
    
         
             
                    version: '0'
         
     | 
| 
       205 
205 
     | 
    
         
             
            description: Glimmer is a Ruby DSL Framework for Ruby GUI and More, consisting of
         
     | 
| 
       206 
206 
     | 
    
         
             
              a DSL Engine and an Observable / Observer / Data-Binding Library (including Observable
         
     | 
| 
       207 
207 
     | 
    
         
             
              Model, Observable Array, and Observable Hash). Used in Glimmer DSL for SWT (JRuby
         
     | 
| 
       208 
     | 
    
         
            -
              Desktop Development GUI Framework), Glimmer DSL for  
     | 
| 
       209 
     | 
    
         
            -
               
     | 
| 
       210 
     | 
    
         
            -
               
     | 
| 
       211 
     | 
    
         
            -
               
     | 
| 
      
 208 
     | 
    
         
            +
              Desktop Development GUI Framework), Glimmer DSL for Opal (Pure Ruby Web GUI and
         
     | 
| 
      
 209 
     | 
    
         
            +
              Auto-Webifier of Desktop Apps), Glimmer DSL for Tk (Ruby Desktop Development GUI
         
     | 
| 
      
 210 
     | 
    
         
            +
              Library), Glimmer DSL for LibUI (Prerequisite-Free Ruby Desktop Development GUI
         
     | 
| 
      
 211 
     | 
    
         
            +
              Library), Glimmer DSL for GTK (Ruby-GNOME Desktop Development GUI Library), Glimmer
         
     | 
| 
      
 212 
     | 
    
         
            +
              DSL for XML (& HTML), and Glimmer DSL for CSS.
         
     | 
| 
       212 
213 
     | 
    
         
             
            email: andy.am@gmail.com
         
     | 
| 
       213 
214 
     | 
    
         
             
            executables: []
         
     | 
| 
       214 
215 
     | 
    
         
             
            extensions: []
         
     | 
| 
         @@ -230,6 +231,7 @@ files: 
     | 
|
| 
       230 
231 
     | 
    
         
             
            - lib/glimmer/data_binding/observable.rb
         
     | 
| 
       231 
232 
     | 
    
         
             
            - lib/glimmer/data_binding/observable_array.rb
         
     | 
| 
       232 
233 
     | 
    
         
             
            - lib/glimmer/data_binding/observable_hash.rb
         
     | 
| 
      
 234 
     | 
    
         
            +
            - lib/glimmer/data_binding/observable_hashable.rb
         
     | 
| 
       233 
235 
     | 
    
         
             
            - lib/glimmer/data_binding/observable_model.rb
         
     | 
| 
       234 
236 
     | 
    
         
             
            - lib/glimmer/data_binding/observer.rb
         
     | 
| 
       235 
237 
     | 
    
         
             
            - lib/glimmer/data_binding/shine.rb
         
     |