cushion_defaults 0.5.2 → 0.6.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -0
- data/README.md +1 -1
- data/lib/cushion_defaults.rb +3 -1
- data/lib/cushion_defaults/class_methods.rb +188 -26
- data/lib/cushion_defaults/defaults_hash.rb +17 -8
- metadata +2 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 2a848b1a32c350596b23bfc77dfc4203f4752f89
         | 
| 4 | 
            +
              data.tar.gz: 5f1af47223822f820d3b6b6846534e8b5c56617c
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 1c69bed3724da4b17b32a6acaf7974598e05eb97cf236d1e784c3ef1d9457e126f6e577e3027b98f5dfb95c0987fec56148dc6fc7b4c64fa08cdeabc5821d123
         | 
| 7 | 
            +
              data.tar.gz: 09fec36978d01e46e1774f9f59eddf013b2e43646a41ab4138963edc9c2deb294ee92f8b20d003f8c0307a2c4304fbd74a632cd786f40909565c0e3dc949b544
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,5 +1,19 @@ | |
| 1 1 | 
             
            # CHANGELOG
         | 
| 2 2 |  | 
| 3 | 
            +
            ## 0.6.x
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            - 0.6.0
         | 
| 6 | 
            +
                - PERFORMANCE:
         | 
| 7 | 
            +
                    - Performance gains in `#cushion_reader` of 20-100%. Now roughly comparable to `attr_reader`.
         | 
| 8 | 
            +
                    - In total, execution speed of `#cushion_reader` is 200-400% faster than in v. 0.0.0.
         | 
| 9 | 
            +
                - API CHANGE:
         | 
| 10 | 
            +
                    - The following methods have been deprecated.
         | 
| 11 | 
            +
                        - `ClassMethods#remove_reader` (see `ClassMethods#remove_cushion_reader`)
         | 
| 12 | 
            +
                        - `ClassMethods#remove_bang` (see `ClassMethods#remove_cushion_bang`)
         | 
| 13 | 
            +
                        - `ClassMethods#remove_writer` (see `ClassMethods#remove_writer`)
         | 
| 14 | 
            +
                    - The now-deprecated methods, when called for `sym`, would remove any method that fit the appropriate reader/bang/writer naming convention. The new methods will only remove CushionDefaults-defined methods.
         | 
| 15 | 
            +
                    - Making a default pushy or polite now automatically declares a cushion_reader for that default in the relevant class.
         | 
| 16 | 
            +
             | 
| 3 17 | 
             
            ## 0.5.x
         | 
| 4 18 |  | 
| 5 19 | 
             
            - 0.5.2: PERFORMANCE
         | 
    
        data/README.md
    CHANGED
    
    | @@ -647,6 +647,6 @@ When you need or want... | |
| 647 647 |  | 
| 648 648 | 
             
            ### When *Shouldn't* I Use CushionDefaults?
         | 
| 649 649 |  | 
| 650 | 
            -
            1. *When speed is absolutely critical.* CushionDefaults is  | 
| 650 | 
            +
            1. *When speed is absolutely critical.* CushionDefaults is very fast (see `benchmarks/simple_benchmark.rb`), since it runs almost entirely on a series of hash lookups and adjusts methods on the fly depending on the current defaults setting. But there's no way it could consistently be as fast as `attr_accessor`: it just does more, and more computations means more time. Current benchmarks show execution speeds of 1.1 to 1.6 times those of `attr_reader` in Ruby 2.1.5, with a smaller factor in Ruby 1.9.3—but this is a difference of 0.01s to 0.05s for 100,000 calls to the reader methods. If you have hundreds of thousands of calculations that you need performed lightning fast, you should look elsewhere; but otherwise, CushionReader should be fast enough for your purposes.
         | 
| 651 651 | 
             
            2. *When working in a Rails environment.* CushionDefaults may eventually spawn a companion project CushionDefaults-Rails, but for now it's just not the right tool for a Rails job. There are plenty of libraries that would be better for this purpose, e.g., [default_value_for](https://github.com/FooBarWidget/default_value_for).
         | 
| 652 652 | 
             
            3. *When you want to keep your dependencies down.* Some people end up with 150 apps on their phones; others end up with 150 gems in their projects. CushionDefaults itself doesn't depend on any other gems (in production), but that still doesn't mean it's worth the extra overhead to use it in every project.
         | 
    
        data/lib/cushion_defaults.rb
    CHANGED
    
    | @@ -31,7 +31,7 @@ require 'cushion_defaults/errors' | |
| 31 31 | 
             
            module CushionDefaults
         | 
| 32 32 |  | 
| 33 33 | 
             
              # Version constant
         | 
| 34 | 
            -
              VERSION = '0. | 
| 34 | 
            +
              VERSION = '0.6.0'
         | 
| 35 35 |  | 
| 36 36 | 
             
              # The path of the first file that includes CushionDefaults.
         | 
| 37 37 | 
             
              CALLING_PATH = File.expand_path(File.dirname($0)) + '/'
         | 
| @@ -135,6 +135,8 @@ module CushionDefaults | |
| 135 135 |  | 
| 136 136 | 
             
                base.extend(ClassMethods)
         | 
| 137 137 |  | 
| 138 | 
            +
                base.send :_set_up_cushion_method_sets
         | 
| 139 | 
            +
             | 
| 138 140 | 
             
                if @conf.auto_load_from_yaml
         | 
| 139 141 | 
             
                  base.defaults_from_yaml
         | 
| 140 142 | 
             
                else
         | 
| @@ -1,9 +1,11 @@ | |
| 1 | 
            +
            require 'set'
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            module CushionDefaults
         | 
| 2 4 | 
             
              # A series of class methods to be plopped into any class that includes CushionDefaults.
         | 
| 3 5 | 
             
              module ClassMethods
         | 
| 4 6 |  | 
| 5 7 | 
             
                # Reader for the @defaults@ @DefaultsHash@.
         | 
| 6 | 
            -
                attr_reader :defaults
         | 
| 8 | 
            +
                attr_reader :defaults, :descendents
         | 
| 7 9 |  | 
| 8 10 | 
             
                # @!attribute [w] defaults
         | 
| 9 11 | 
             
                # Wipe @defaults and replace it with the keys/vals of @replacement_hash@.
         | 
| @@ -73,6 +75,15 @@ module CushionDefaults | |
| 73 75 | 
             
                  end
         | 
| 74 76 | 
             
                end
         | 
| 75 77 |  | 
| 78 | 
            +
                def _set_up_cushion_method_sets
         | 
| 79 | 
            +
                  @have_cushion_readers = Set.new
         | 
| 80 | 
            +
                  @have_bang_readers = Set.new
         | 
| 81 | 
            +
                  @have_cushion_writers = Set.new
         | 
| 82 | 
            +
                  @descendents = Set.new
         | 
| 83 | 
            +
                end
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                private :_set_up_cushion_method_sets
         | 
| 86 | 
            +
             | 
| 76 87 | 
             
                # @!group Reader/Writer
         | 
| 77 88 |  | 
| 78 89 | 
             
                # Sets up a cushion_reader for each :sym in @syms@.
         | 
| @@ -93,30 +104,80 @@ module CushionDefaults | |
| 93 104 | 
             
                # @param syms [*#to_sym] instance variables that should have @cushion_readers@
         | 
| 94 105 | 
             
                # @see Configuration#update_readers
         | 
| 95 106 | 
             
                def cushion_reader(*syms)
         | 
| 96 | 
            -
                   | 
| 97 | 
            -
             | 
| 98 | 
            -
             | 
| 99 | 
            -
             | 
| 100 | 
            -
                    end
         | 
| 101 | 
            -
                    instance_variable_sym = "@#{sym}".to_sym
         | 
| 107 | 
            +
                  # send it with force==true
         | 
| 108 | 
            +
                  syms.each { |sym| _update_cushion_reader(sym.to_sym, true) }
         | 
| 109 | 
            +
                  bang_reader *syms if CushionDefaults.conf.bang_things_up
         | 
| 110 | 
            +
                end
         | 
| 102 111 |  | 
| 103 | 
            -
             | 
| 104 | 
            -
             | 
| 112 | 
            +
                # @api private
         | 
| 113 | 
            +
                def _define_cushion_reader_pushy_dynamic(sym)
         | 
| 114 | 
            +
                  defaults_cache = @defaults
         | 
| 115 | 
            +
                  define_method(sym) do
         | 
| 116 | 
            +
                    defaults_cache[sym].call(self, sym)
         | 
| 117 | 
            +
                    da_default.respond_to?(:call) ? da_default.call(self, sym) : da_default
         | 
| 118 | 
            +
                  end
         | 
| 119 | 
            +
                end
         | 
| 105 120 |  | 
| 106 | 
            -
             | 
| 107 | 
            -
             | 
| 108 | 
            -
             | 
| 109 | 
            -
             | 
| 110 | 
            -
             | 
| 111 | 
            -
                        da_default = defaults_cache[sym]
         | 
| 112 | 
            -
                        da_default.respond_to?(:call) ? da_default.call(self, sym) : da_default
         | 
| 113 | 
            -
                      end
         | 
| 114 | 
            -
                    end
         | 
| 115 | 
            -
                    CushionDefaults.log("cushion_reader #{sym} established for #{self}")
         | 
| 121 | 
            +
                # @api private
         | 
| 122 | 
            +
                def _define_cushion_reader_pushy_static(sym)
         | 
| 123 | 
            +
                  defaults_cache = @defaults
         | 
| 124 | 
            +
                  define_method(sym) do
         | 
| 125 | 
            +
                    defaults_cache[sym]
         | 
| 116 126 | 
             
                  end
         | 
| 117 | 
            -
                  bang_reader *syms if CushionDefaults.conf.bang_things_up
         | 
| 118 127 | 
             
                end
         | 
| 119 128 |  | 
| 129 | 
            +
                # @api private
         | 
| 130 | 
            +
                def _define_cushion_reader_no_pushy_dynamic(sym)
         | 
| 131 | 
            +
                  defaults_cache = @defaults
         | 
| 132 | 
            +
                  instance_variable_sym = "@#{sym}".to_sym
         | 
| 133 | 
            +
                  define_method(sym) do
         | 
| 134 | 
            +
                    instance_variable_defined?(instance_variable_sym) ? instance_variable_get(instance_variable_sym) : defaults_cache[sym].call(self, sym)
         | 
| 135 | 
            +
                  end
         | 
| 136 | 
            +
                end
         | 
| 137 | 
            +
             | 
| 138 | 
            +
                # @api private
         | 
| 139 | 
            +
                def _define_cushion_reader_no_pushy_static(sym)
         | 
| 140 | 
            +
                  defaults_cache = @defaults
         | 
| 141 | 
            +
                  instance_variable_sym = "@#{sym}".to_sym
         | 
| 142 | 
            +
                  define_method(sym) do
         | 
| 143 | 
            +
                    instance_variable_defined?(instance_variable_sym) ? instance_variable_get(instance_variable_sym) : defaults_cache[sym]
         | 
| 144 | 
            +
                  end
         | 
| 145 | 
            +
                end
         | 
| 146 | 
            +
             | 
| 147 | 
            +
                private :_define_cushion_reader_no_pushy_dynamic, :_define_cushion_reader_no_pushy_static, :_define_cushion_reader_pushy_dynamic, :_define_cushion_reader_pushy_static
         | 
| 148 | 
            +
             | 
| 149 | 
            +
                # @param sym [Symbol] the attribute to update the cushion_reader for
         | 
| 150 | 
            +
                # @param force [boolean] if true, it will always update the method
         | 
| 151 | 
            +
                # @api private
         | 
| 152 | 
            +
                def _update_cushion_reader(sym, force=false)
         | 
| 153 | 
            +
                  # This will redefine a method each time the default is changed, but at this point that does not seem like a big
         | 
| 154 | 
            +
                  # enough performance hit to warrant the checks required to avoid it.
         | 
| 155 | 
            +
             | 
| 156 | 
            +
                  # force: should we force it to continue? (Basically should only be forced by {#cushion_reader})
         | 
| 157 | 
            +
                  # include?: if the reader already exists (i.e., it was previously manually created) then continue
         | 
| 158 | 
            +
                  # update_readers: if we're updating readers automatically, then continue
         | 
| 159 | 
            +
                  return unless force || @have_cushion_readers.include?(sym) || CushionDefaults.conf.update_readers
         | 
| 160 | 
            +
             | 
| 161 | 
            +
                  # include?: so we only show this warning once
         | 
| 162 | 
            +
                  if !@have_cushion_readers.include?(sym) && self_or_parent_instance_method?(sym)
         | 
| 163 | 
            +
                    CushionDefaults.log("#{self} or a parent class already has what looks like an attr_reader for #{sym}", :warn)
         | 
| 164 | 
            +
                  end
         | 
| 165 | 
            +
             | 
| 166 | 
            +
                  # Create one of four cushion_reader methods depending on the state and type of the default value
         | 
| 167 | 
            +
                  if @defaults.pushy? sym
         | 
| 168 | 
            +
                    @defaults[sym].respond_to?(:call) ? _define_cushion_reader_pushy_dynamic(sym) : _define_cushion_reader_pushy_static(sym)
         | 
| 169 | 
            +
                  else
         | 
| 170 | 
            +
                    default = @defaults[sym]
         | 
| 171 | 
            +
                    default.respond_to?(:call) ? _define_cushion_reader_no_pushy_dynamic(sym) : _define_cushion_reader_no_pushy_static(sym)
         | 
| 172 | 
            +
                  end
         | 
| 173 | 
            +
                  @have_cushion_readers.add sym
         | 
| 174 | 
            +
                  CushionDefaults.log("cushion_reader #{sym} updated for #{self}")
         | 
| 175 | 
            +
                end
         | 
| 176 | 
            +
             | 
| 177 | 
            +
                private :_update_cushion_reader
         | 
| 178 | 
            +
             | 
| 179 | 
            +
             | 
| 180 | 
            +
             | 
| 120 181 | 
             
                # Identical to {#cushion_reader} with one important exception: after determining the default value, @bang_reader@
         | 
| 121 182 | 
             
                # goes on to crystallize this default value for the instance.
         | 
| 122 183 | 
             
                #
         | 
| @@ -224,39 +285,95 @@ module CushionDefaults | |
| 224 285 | 
             
                  end
         | 
| 225 286 | 
             
                end
         | 
| 226 287 |  | 
| 227 | 
            -
                # Undefines the reader for sym in this class (if present).
         | 
| 288 | 
            +
                # Undefines the reader for sym in this class (if present). Does not affect ancestor classes.
         | 
| 228 289 | 
             
                # @note This method will delete any method of the form @sym@, not just cushion_readers.
         | 
| 229 290 | 
             
                # @param sym [#to_sym] instance variable to delete reader for
         | 
| 291 | 
            +
                # @deprecated
         | 
| 230 292 | 
             
                def remove_reader(sym)
         | 
| 231 293 | 
             
                  sym = sym.to_sym
         | 
| 232 294 | 
             
                  if self_has_method?(sym)
         | 
| 295 | 
            +
                    undef_method(sym)
         | 
| 296 | 
            +
                    @have_cushion_readers.delete(sym)
         | 
| 297 | 
            +
                    CushionDefaults.log("cushion_reader #{sym} removed from #{self}", :info)
         | 
| 298 | 
            +
                  end
         | 
| 299 | 
            +
                end
         | 
| 300 | 
            +
             | 
| 301 | 
            +
                # Undefines the cushion_reader for sym in this class (if present). Does not affect ancestor classes.
         | 
| 302 | 
            +
                # @param sym [#to_sym] instance variable to delete cushion_reader for
         | 
| 303 | 
            +
                def remove_cushion_reader(sym)
         | 
| 304 | 
            +
                  sym = sym.to_sym
         | 
| 305 | 
            +
                  if @have_cushion_readers.delete?(sym) && self_has_method?(sym)
         | 
| 233 306 | 
             
                    undef_method(sym)
         | 
| 234 307 | 
             
                    CushionDefaults.log("cushion_reader #{sym} removed from #{self}", :info)
         | 
| 235 308 | 
             
                  end
         | 
| 236 309 | 
             
                end
         | 
| 237 310 |  | 
| 238 | 
            -
                # Undefines any bang method for sym in this class (if present).
         | 
| 311 | 
            +
                # Undefines any bang method for sym in this class (if present). Does not affect ancestor classes.
         | 
| 239 312 | 
             
                # @note This method will delete any method of the form @sym!@, not just bang readers.
         | 
| 240 313 | 
             
                # @param sym [#to_sym] instance variable to delete bang method for
         | 
| 314 | 
            +
                # @deprecated
         | 
| 241 315 | 
             
                def remove_bang(sym)
         | 
| 242 | 
            -
                  sym = "sym!".to_sym
         | 
| 316 | 
            +
                  sym = "#{sym}!".to_sym
         | 
| 243 317 | 
             
                  if self_has_method?(sym)
         | 
| 318 | 
            +
                    undef_method(sym)
         | 
| 319 | 
            +
                    @have_bang_readers.delete(sym)
         | 
| 320 | 
            +
                    CushionDefaults.log("bang reader #{sym} removed from #{self}", :info)
         | 
| 321 | 
            +
                  end
         | 
| 322 | 
            +
                end
         | 
| 323 | 
            +
             | 
| 324 | 
            +
                # Undefines any bang method for sym in this class (if present). Does not affect ancestor classes.
         | 
| 325 | 
            +
                # @note This method will delete any method of the form @sym!@, not just bang readers.
         | 
| 326 | 
            +
                # @param sym [#to_sym] instance variable to delete bang method for
         | 
| 327 | 
            +
                def remove_cushion_bang(sym)
         | 
| 328 | 
            +
                  sym = "#{sym}!".to_sym
         | 
| 329 | 
            +
                  if @have_bang_readers.delete?(sym) && self_has_method?(sym)
         | 
| 244 330 | 
             
                    undef_method(sym)
         | 
| 245 331 | 
             
                    CushionDefaults.log("bang reader #{sym} removed from #{self}", :info)
         | 
| 246 332 | 
             
                  end
         | 
| 247 333 | 
             
                end
         | 
| 248 334 |  | 
| 249 | 
            -
                # Undefines any writer for sym in this class (if present).
         | 
| 335 | 
            +
                # Undefines any writer for sym in this class (if present). Does not affect ancestor classes.
         | 
| 250 336 | 
             
                # @note This method will delete any method of the format 'sym=', not just cushion_writers.
         | 
| 251 337 | 
             
                # @param sym [#to_sym] instance variable to delete writer for
         | 
| 338 | 
            +
                # @deprecated
         | 
| 252 339 | 
             
                def remove_writer(sym)
         | 
| 253 340 | 
             
                  write_sym = "#{sym}=".to_sym
         | 
| 254 341 | 
             
                  if self_has_method?(write_sym)
         | 
| 342 | 
            +
                    undef_method(write_sym)
         | 
| 343 | 
            +
                    @have_cushion_writers.delete(write_sym)
         | 
| 344 | 
            +
                    CushionDefaults.log("cushion_writer #{sym}= removed from #{self}", :info)
         | 
| 345 | 
            +
                  end
         | 
| 346 | 
            +
                end
         | 
| 347 | 
            +
             | 
| 348 | 
            +
                # Undefines any writer for sym in this class (if present). Does not affect ancestor classes.
         | 
| 349 | 
            +
                # @note This method will delete any method of the format 'sym=', not just cushion_writers.
         | 
| 350 | 
            +
                # @param sym [#to_sym] instance variable to delete writer for
         | 
| 351 | 
            +
                def remove_cushion_writer(sym)
         | 
| 352 | 
            +
                  write_sym = "#{sym}=".to_sym
         | 
| 353 | 
            +
                  if @have_cushion_writers.delete?(write_sym) && self_has_method?(write_sym)
         | 
| 255 354 | 
             
                    undef_method(write_sym)
         | 
| 256 355 | 
             
                    CushionDefaults.log("cushion_writer #{sym}= removed from #{self}", :info)
         | 
| 257 356 | 
             
                  end
         | 
| 258 357 | 
             
                end
         | 
| 259 358 |  | 
| 359 | 
            +
                def _hide_cushion_reader(sym)
         | 
| 360 | 
            +
                  # Called (1) when a cushion reader exists and (2) the reader needs to be hidden
         | 
| 361 | 
            +
                  alias_method "_#{sym}_hidden".to_sym, sym
         | 
| 362 | 
            +
                  remove_method sym
         | 
| 363 | 
            +
                end
         | 
| 364 | 
            +
             | 
| 365 | 
            +
                def _reveal_cushion_reader(sym)
         | 
| 366 | 
            +
                  # Called (1) when a previous cushion reader exists but (2) it was hidden due to a parent's sym becoming pushy
         | 
| 367 | 
            +
                  alias_method sym, "_#{sym}_hidden".to_sym
         | 
| 368 | 
            +
                  remove_method "_#{sym}_hidden".to_sym
         | 
| 369 | 
            +
                  # Things might have changed, so we should update the method
         | 
| 370 | 
            +
                  @have_cushion_readers.add sym
         | 
| 371 | 
            +
                  _update_cushion_reader sym
         | 
| 372 | 
            +
                end
         | 
| 373 | 
            +
             | 
| 374 | 
            +
                private :_hide_cushion_reader, :_reveal_cushion_reader
         | 
| 375 | 
            +
             | 
| 376 | 
            +
             | 
| 260 377 | 
             
                # Sets up both {#cushion_reader}s and {#cushion_writer}s for @syms@. Will set up {#bang_reader}s if
         | 
| 261 378 | 
             
                # {CushionDefaults::Configuration#bang_things_up Configuration#bang_things_up} is true.
         | 
| 262 379 | 
             
                # @param syms [*#to_sym] Those instance variables that should have {#cushion_reader}s and {#cushion_writer}s.
         | 
| @@ -377,16 +494,59 @@ module CushionDefaults | |
| 377 494 |  | 
| 378 495 | 
             
                # Declare each sym to be pushy. Pushy defaults will be returned by {#cushion_reader}s regardless of what the
         | 
| 379 496 | 
             
                # instance variables are set to.
         | 
| 497 | 
            +
                #
         | 
| 498 | 
            +
                # This will automatically create {#cushion_reader}'s for all variables made pushy.
         | 
| 380 499 | 
             
                def make_pushy(*syms)
         | 
| 381 | 
            -
                  syms.each  | 
| 500 | 
            +
                  syms.each do |sym|
         | 
| 501 | 
            +
                    @defaults.pushy!(sym)
         | 
| 502 | 
            +
                    _update_cushion_reader(sym, true)
         | 
| 503 | 
            +
                  end
         | 
| 382 504 | 
             
                end
         | 
| 383 505 |  | 
| 384 506 | 
             
                # Declare each sym to be polite. A polite default operates as normal. This is useful to override an ancestor class'
         | 
| 385 507 | 
             
                # pushy declaration.
         | 
| 508 | 
            +
                #
         | 
| 509 | 
            +
                # This will automatically create {#cushion_reader}'s for all variables made polite.
         | 
| 386 510 | 
             
                def make_polite(*syms)
         | 
| 387 | 
            -
                  syms.each  | 
| 511 | 
            +
                  syms.each do |sym|
         | 
| 512 | 
            +
                    @defaults.not_pushy!(sym)
         | 
| 513 | 
            +
                    _update_cushion_reader(sym, true)
         | 
| 514 | 
            +
                  end
         | 
| 388 515 | 
             
                end
         | 
| 389 516 |  | 
| 517 | 
            +
                # Called when a variable either becomes pushy or _may_ have become pushy.
         | 
| 518 | 
            +
                def _cascade_pushy_symbol(sym)
         | 
| 519 | 
            +
                  # if we get down far enough, it may no longer be pushy (we read a polite)
         | 
| 520 | 
            +
                  # at that point, we can assume accurate state
         | 
| 521 | 
            +
                  return unless @defaults.pushy? sym
         | 
| 522 | 
            +
                  if self_has_method? sym
         | 
| 523 | 
            +
                    if @defaults.pushy_in_parent? sym
         | 
| 524 | 
            +
                      # if it's pushy in a parent now, then hide the reader
         | 
| 525 | 
            +
                      # we hide it rather than delete it because we want to be able to restore a manually-created cushion_reader if
         | 
| 526 | 
            +
                      # this is later made not-polite
         | 
| 527 | 
            +
                      _hide_cushion_reader sym
         | 
| 528 | 
            +
                      @have_cushion_readers.delete sym
         | 
| 529 | 
            +
                      # cascade it down to descendents
         | 
| 530 | 
            +
                      @descendents.each { |desc| desc._cascade_pushy_symbol sym if respond_to? :_cascade_pushy_symbol }
         | 
| 531 | 
            +
                    else
         | 
| 532 | 
            +
                      # if it's pushy in us (has to be, if not pushy in parent) then just update the reader
         | 
| 533 | 
            +
                      _update_cushion_reader sym
         | 
| 534 | 
            +
                      # also, if it's pushy in us, we don't need to look at descendents any more, so no need to call
         | 
| 535 | 
            +
                    end
         | 
| 536 | 
            +
                  end
         | 
| 537 | 
            +
                end
         | 
| 538 | 
            +
             | 
| 539 | 
            +
                # Called when a variable either becomes polite or _may_ have become polite.
         | 
| 540 | 
            +
                def _cascade_polite_symbol(sym)
         | 
| 541 | 
            +
                  # if we get down far enough, it may become pushy again
         | 
| 542 | 
            +
                  return unless @defaults.not_pushy? sym
         | 
| 543 | 
            +
                  _reveal_cushion_reader(sym) if self_has_method? "_#{sym}_hidden".to_sym
         | 
| 544 | 
            +
                  # cascade it down to descendents
         | 
| 545 | 
            +
                  @descendents.each { |desc| desc._cascade_polite_symbol sym if respond_to? :_cascade_polite_symbol }
         | 
| 546 | 
            +
                end
         | 
| 547 | 
            +
             | 
| 548 | 
            +
                private :_cascade_pushy_symbol, :_cascade_polite_symbol
         | 
| 549 | 
            +
             | 
| 390 550 | 
             
                # @!endgroup
         | 
| 391 551 |  | 
| 392 552 | 
             
                # Ensure that if class @Klass@ includes @CushionDefaults@, then any class that subclasses @Klass@ will include it as
         | 
| @@ -396,6 +556,8 @@ module CushionDefaults | |
| 396 556 | 
             
                # @api private
         | 
| 397 557 | 
             
                def inherited(inheritor)
         | 
| 398 558 | 
             
                  inheritor.send :include, CushionDefaults
         | 
| 559 | 
            +
                  @descendents << inheritor
         | 
| 560 | 
            +
                  super inheritor
         | 
| 399 561 | 
             
                end
         | 
| 400 562 |  | 
| 401 563 | 
             
                protected
         | 
| @@ -77,8 +77,9 @@ module CushionDefaults | |
| 77 77 | 
             
                  key = key.to_sym
         | 
| 78 78 | 
             
                  return unless has_key? key
         | 
| 79 79 | 
             
                  remove_methods_as_needed(key)
         | 
| 80 | 
            -
                  @pushy_defaults. | 
| 81 | 
            -
                  @ | 
| 80 | 
            +
                  #TODO Need some better way to handle when @pushy_defaults is emptied or cleared. Need to talk to children.
         | 
| 81 | 
            +
                  @owner.send :_cascade_polite_symbol, key if @pushy_defaults.delete? key
         | 
| 82 | 
            +
                  @owner.send :_cascade_pushy_symbol, key if @polite_defaults.delete? key
         | 
| 82 83 | 
             
                  @frozen_defaults.delete(key)
         | 
| 83 84 | 
             
                  super(key)
         | 
| 84 85 | 
             
                  CushionDefaults.log("Default for #{key} in #{@owner} deleted.")
         | 
| @@ -89,9 +90,9 @@ module CushionDefaults | |
| 89 90 | 
             
                def clear
         | 
| 90 91 | 
             
                  keys.each do |key|
         | 
| 91 92 | 
             
                    remove_methods_as_needed(key.to_sym)
         | 
| 93 | 
            +
                    @owner.send :_cascade_polite_symbol, key if @pushy_defaults.delete? key
         | 
| 94 | 
            +
                    @owner.send :_cascade_pushy_symbol, key if @pushy_defaults.delete? key
         | 
| 92 95 | 
             
                  end
         | 
| 93 | 
            -
                  @pushy_defaults.clear
         | 
| 94 | 
            -
                  @polite_defaults.clear
         | 
| 95 96 | 
             
                  @frozen_defaults.clear
         | 
| 96 97 | 
             
                  super
         | 
| 97 98 | 
             
                  CushionDefaults.log("All defaults cleared for #{@owner}.", :info)
         | 
| @@ -163,6 +164,9 @@ module CushionDefaults | |
| 163 164 | 
             
                  CushionDefaults.conf.we_have_a_pushy!
         | 
| 164 165 | 
             
                  @pushy_defaults.add(sym)
         | 
| 165 166 | 
             
                  @polite_defaults.delete(sym)
         | 
| 167 | 
            +
             | 
| 168 | 
            +
                  @owner.send :_cascade_pushy_symbol, sym
         | 
| 169 | 
            +
             | 
| 166 170 | 
             
                  CushionDefaults.log(":#{sym} in #{@owner} is now pushy.")
         | 
| 167 171 | 
             
                end
         | 
| 168 172 |  | 
| @@ -170,6 +174,11 @@ module CushionDefaults | |
| 170 174 | 
             
                def not_pushy!(sym)
         | 
| 171 175 | 
             
                  @pushy_defaults.delete(sym)
         | 
| 172 176 | 
             
                  @polite_defaults.add(sym)
         | 
| 177 | 
            +
             | 
| 178 | 
            +
                  @owner.send :_cascade_polite_symbol, sym
         | 
| 179 | 
            +
             | 
| 180 | 
            +
                  # we may need now to define a reader for it
         | 
| 181 | 
            +
                  @owner.send :_update_cushion_reader, sym
         | 
| 173 182 | 
             
                  CushionDefaults.log("#{sym} in #{@owner} is now polite.")
         | 
| 174 183 | 
             
                end
         | 
| 175 184 |  | 
| @@ -220,7 +229,7 @@ module CushionDefaults | |
| 220 229 | 
             
                # @see Configuration#update_writers
         | 
| 221 230 | 
             
                # @see ClassMethods#cushion
         | 
| 222 231 | 
             
                def add_methods_as_needed(key)
         | 
| 223 | 
            -
                  @owner. | 
| 232 | 
            +
                  @owner.send :_update_cushion_reader, key
         | 
| 224 233 | 
             
                  @owner.cushion_writer key.to_sym if CushionDefaults.conf.update_writers
         | 
| 225 234 | 
             
                end
         | 
| 226 235 |  | 
| @@ -231,9 +240,9 @@ module CushionDefaults | |
| 231 240 | 
             
                # @see ClassMethods#remove_reader
         | 
| 232 241 | 
             
                # @see ClassMethods#remove_writer
         | 
| 233 242 | 
             
                def remove_methods_as_needed(key)
         | 
| 234 | 
            -
                  @owner. | 
| 235 | 
            -
                  @owner. | 
| 236 | 
            -
                  @owner. | 
| 243 | 
            +
                  @owner.remove_cushion_reader key.to_sym if CushionDefaults.conf.update_readers
         | 
| 244 | 
            +
                  @owner.remove_bang_reader key.to_sym if CushionDefaults.conf.update_readers
         | 
| 245 | 
            +
                  @owner.remove_cushion_writer key.to_sym if CushionDefaults.conf.update_writers
         | 
| 237 246 | 
             
                end
         | 
| 238 247 |  | 
| 239 248 | 
             
                protected
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: cushion_defaults
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 0.6.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Ryan Mitchell
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2014-12- | 
| 11 | 
            +
            date: 2014-12-13 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: rspec
         |