cushion_defaults 0.3.1 → 0.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e7fd6692745ad995ce699917618f66bf08ba58a4
4
- data.tar.gz: 8e17dbed0aae4f20cb657ebb2dc1e7113bd9b31c
3
+ metadata.gz: e4ae7cc718182c777f0867383128216f35841d45
4
+ data.tar.gz: d7735d85bada9bb54e534fa2eb1ffc4b826711e5
5
5
  SHA512:
6
- metadata.gz: 7cb89e14bc6fd047ee279443012fe41c103699e5ad6e87ee8c8bf4d1c8e49e671e88cbc03624eb4122dd846b4a508891365cdeeeca3dbb1b96997aec92973b43
7
- data.tar.gz: 68740c0fdb797b9b32dddeaf470f72530b8216ac188edaa7b7da406ed1dbee283990bb24a3dff1d8e66e554e1f13fbc921f95f502278178e56ebce47b27453fb
6
+ metadata.gz: 179c1e3ad13f662357a1baad18902a11ef2e10e1c8acf19d14ae5e1a18855a10f5daafbab9fdd8b840ca61f916e30b79a1a1d9a39e7f6b689a903e7423675f86
7
+ data.tar.gz: ffef5ddacf6255e6dc576d9c4e0dbf618396168c9c3a35d207e54515cd886e548683eaae0f6f0514f400172d2ed826910290332bc29990d22be6600072c9e9bd
data/CHANGELOG.md CHANGED
@@ -46,4 +46,10 @@
46
46
  - ClassMethods#freeze_default
47
47
  - ClassMethods#deep_freeze_default
48
48
  - ClassMethods#thaw_default
49
- - 0.3.1: Bugfix to #freeze_defaults, #deep_freeze_defaults, and #thaw_defaults
49
+ - 0.3.1: Bugfix to #freeze_defaults, #deep_freeze_defaults, and #thaw_defaults
50
+
51
+ ## 0.4.x
52
+
53
+ -0.4.0 - NEW FEATURE: Proc Cushions
54
+ - You can now set a default to a proc that will be evaluated whenever an instance variable is absent.
55
+ - For more information, see "Proc Cushions" in README.md.
data/README.md CHANGED
@@ -47,9 +47,12 @@ julia.favorite_color # 'green'
47
47
  ## How Do I Get It?
48
48
  `gem install 'cushion_defaults'` if you just want the gem.
49
49
 
50
- If you want to help out the project or edit the source code, clone the repository (hosted at [GitHub](https://github.com/posgarou/cushion_defaults)).
50
+ If you want to help out the project or edit the source code, clone the repository (hosted at [GitHub](https://github.com/posgarou/cushion_defaults)), fork it, make changes, and make a pull request.
51
+
51
52
  ## Give Me the Rundown
53
+
52
54
  ### The Basics
55
+
53
56
  Setting up a DefaultsHash, populating it, and setting up `cushion_reader`s and `cushion_writer`s is a simple process.
54
57
 
55
58
  ```ruby
@@ -206,6 +209,80 @@ update_readers: true
206
209
  update_writers: true
207
210
  ```
208
211
 
212
+ ### Proc Cushions
213
+
214
+ CushionDefaults now supports proc cushions, which offer a powerful new level of flexibility in getting and setting defaults.
215
+
216
+ If a default is set to a Proc, then cushion_readers will yield both an instance variable and a symbol representing the instance variable queried. (Since it's a proc, though, we do not need to worry about everything passed in.)
217
+
218
+ Take the following example:
219
+
220
+ ```ruby
221
+ class Language
222
+ attr_accessor :greeting
223
+ def initialize(&block)
224
+ yield self if block_given?
225
+ end
226
+ end
227
+
228
+ $languages = {
229
+ en: Language.new { |l| l.greeting = 'Hello' },
230
+ fr: Language.new { |l| l.greeting = 'Bonjour' }
231
+ }
232
+
233
+ class Person
234
+ include CushionDefaults
235
+
236
+ self.defaults[:language] = $languages[:en]
237
+
238
+ # By default, return the greeting for the instance's language
239
+ self.defaults[:greeting] = proc do |instance|
240
+ instance.language.greeting
241
+ end
242
+
243
+ cushion_defaults
244
+ end
245
+
246
+ john = Person.new
247
+ john.greeting # 'Hello'
248
+
249
+ pierre = Person.new
250
+ pierre.greeting # 'Hello', since languages[:en] is the default language
251
+
252
+ pierre.language = $languages[:fr]
253
+ pierre.greeting # 'Bonjour', since languages[:fr] is now pierre's greeting
254
+
255
+ pierre.greeting = 'Salut!'
256
+ pierre.greeting # 'Salut!', since pierre has a custom greeting
257
+
258
+ ```
259
+
260
+ It is also possible to combine this technique with calls to writer methods to produce a lazily-evaluated instance variable.
261
+
262
+ ```ruby
263
+ class Person
264
+ include CushionDefaults
265
+
266
+ self.defaults[:when_i_noticed_you] = proc do |instance|
267
+ instance.when_i_noticed_you = Time.now
268
+ end
269
+
270
+ cushion :when_i_noticed_you
271
+ end
272
+
273
+ passerby = Person.new
274
+
275
+ # since @when_i_noticed_you is undefined, above proc sets it to Time.now
276
+ passerby.when_i_noticed_you # Time.now
277
+
278
+ # wait a sec
279
+ sleep(1.0)
280
+
281
+ passerby.when_i_noticed_you == Time.now # false—1 sec later
282
+ ```
283
+
284
+ These two techniques can provide sophisticated means of both setting cushions or defaults while allowing customizable values for particular instances.
285
+
209
286
  ### Freezing and Thawing Defaults
210
287
 
211
288
  You may wish to prevent a default from further modification, either permanently or temporarily. This can prevent silly mistakes that are otherwise difficult to track down. CushionDefaults makes this possible via a freezing and thawing API. The key methods here are `#freeze_default` and `#thaw_default`.
@@ -260,7 +337,7 @@ By default, CushionDefaults checks for YAML files for each class but does not co
260
337
 
261
338
  CushionDefaults looks for these YAML files at `config/cushion_defaults/class_name.yaml`. For class Klass, then, it would expect a config file at `config/cushion_defaults/klass.yaml`. Classes in a namespace are expected to have their YAML files in a folder named after their namespace, e.g. Modjewel::Klass in `config/cushion_defaults/modjewel/klass.yaml`.
262
339
 
263
- These YAML files are completely unremarkable in form. Note that all defaults should be specified at root (not in `defaults:`, and currently only simple types are processed. For the above Chair class, we could place the defaults in a YAML class file like the following:
340
+ These YAML files are completely unremarkable in form. Note that all defaults should be specified at root (not in `defaults:`), and currently only simple types are processed. For the above Chair class, we could place the defaults in a YAML class file like the following:
264
341
 
265
342
  ```yaml
266
343
  # config/cushion_defaults/chair.yaml
@@ -83,6 +83,9 @@ module CushionDefaults
83
83
  # The only exception to this rule is when we have pushy defaults. If a default is pushy, we return it regardless of
84
84
  # what this object's instance variable may or may not be.
85
85
  #
86
+ # Note that if the default responds to :call (a proc, e.g.), then the default is instead called with the instance
87
+ # variable and the symbolic representation of the default requested. This allows for proc cushions.
88
+ #
86
89
  # The readers are named according to the same format as +attr_reader+.
87
90
  # @param syms [*#to_sym] instance variables that should have +cushion_readers+
88
91
  # @see Configuration#update_readers
@@ -97,6 +100,8 @@ module CushionDefaults
97
100
  define_method(sym) do
98
101
  if instance_variable_defined?(instance_variable_string) && (CushionDefaults.conf.no_pushies? || defaults.not_pushy?(sym))
99
102
  instance_variable_get(instance_variable_string)
103
+ elsif defaults[sym].respond_to? :call
104
+ defaults[sym].call(self, sym)
100
105
  else
101
106
  defaults[sym]
102
107
  end
@@ -28,7 +28,7 @@ require 'cushion_defaults/errors'
28
28
  module CushionDefaults
29
29
 
30
30
  # Version constant
31
- VERSION = '0.3.1'
31
+ VERSION = '0.4.0'
32
32
 
33
33
  # The path of the first file that +includes+ CushionDefaults.
34
34
  CALLING_PATH = File.expand_path(File.dirname($0)) + '/'
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.3.1
4
+ version: 0.4.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-09 00:00:00.000000000 Z
11
+ date: 2014-12-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec