cushion_defaults 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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