adornable 1.1.0 → 1.1.1

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
  SHA256:
3
- metadata.gz: ece582a2ce4c7093792eacfa04863a2c71a8a5bee12fceb0f964356b58f997c5
4
- data.tar.gz: dabd571e4161e633d40d15bdaccee37bf8646ec7f7cdd2d4773feaeb207c5e9d
3
+ metadata.gz: 3b916559874ffdc52baa8f1b2a75a7e550ad600c501d45adeaf4c53aa0796c97
4
+ data.tar.gz: b7fd7d3eeaaae6b706fbe9f9b9f0d24770351a5ebbbd18759bd96d014466b001
5
5
  SHA512:
6
- metadata.gz: b0dbae5d19cd42fe225b054bb9245ff9946c417d75c1decdb23441be527991a6186a90abaa0ce46faa5ad61cc3dfbfa01d5d0fc063620dbc4bb69db94a44a9f7
7
- data.tar.gz: 58416d66482d8b39ea8ee9b3ac532c6e37b6a2de811542551fe4a857927beb5117bc13ef3a460320f19eaca683bf97939a0e257548fc12a1c81aec39a6c78163
6
+ metadata.gz: b3d49e5efb60aec78d2b416c6d36c8c02844151a6824503f9301db45a4cd392ccea9f316500723e84a07d7ecb200b86a31c71bbc571e3294adfa637a7b92956f
7
+ data.tar.gz: a97a7142ccc356e8657421e32de71f30c6a9070e73a618e5fbaa238ae2b7e3e7193ce11782a942f75b0606d14af54f79a4fd772de83526f200c2da504f353140
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Adornable
2
2
 
3
- Adornable provides method decorators in Ruby... 'nuff said.
3
+ Adornable provides the ability to cleanly decorate methods in Ruby. You can make and use your own decorators, and you can also use some of the built-in ones that the gem provides. _Decorating_ methods is as simple as slapping a `decorate :some_decorator` above your method definition. _Defining_ decorators can be as simple as defining a method that yields to a block, or as complex as manipulating the decorated method's receiver and arguments, and/or changing the functionality of the decorator based on custom options supplied to it when initially applying the decorator.
4
4
 
5
5
  ## Installation
6
6
 
@@ -26,8 +26,6 @@ Alternatively, install it globally:
26
26
  gem install adornable
27
27
  ```
28
28
 
29
- ...but why would you do that?
30
-
31
29
  ## Usage
32
30
 
33
31
  ### The basics
@@ -75,9 +73,9 @@ value2 = random_value_generator.value
75
73
  #=> 0.4196007135344746
76
74
  ```
77
75
 
78
- ...but you have a million more methods to write, and if you refactor, you'll have to screw around with a whole metric butt-load of method definitions across your app.
76
+ However, you have a million more methods to write, and if you refactor, you'll have to screw around with a slew of method definitions across your app.
79
77
 
80
- How about this instead?
78
+ What if you could do this, instead, to achieve the same result?
81
79
 
82
80
  ```rb
83
81
  class RandomValueGenerator
@@ -95,28 +93,6 @@ class RandomValueGenerator
95
93
  (1..max).map { rand }
96
94
  end
97
95
  end
98
-
99
- random_value_generator = RandomValueGenerator.new
100
-
101
- values1 = random_value_generator.values(1000)
102
- # Calling method `RandomValueGenerator#values` with arguments `[1000]`
103
- #=> [0.7044444114998132, 0.401953296596267, 0.3023797513191562, ...]
104
-
105
- values1 = random_value_generator.values(1000)
106
- # Calling method `RandomValueGenerator#values` with arguments `[1000]`
107
- #=> [0.7044444114998132, 0.401953296596267, 0.3023797513191562, ...]
108
-
109
- values3 = random_value_generator.values(5000)
110
- # Calling method `RandomValueGenerator#values` with arguments `[5000]`
111
- #=> [0.9916088057511011, 0.04466750434972333, 0.6073659341272127]
112
-
113
- value1 = random_value_generator.value
114
- # Calling method `RandomValueGenerator#value` with no arguments
115
- #=> 0.4196007135344746
116
-
117
- value2 = random_value_generator.value
118
- # Calling method `RandomValueGenerator#value` with no arguments
119
- #=> 0.4196007135344746
120
96
  ```
121
97
 
122
98
  Nice, right?
@@ -141,7 +117,7 @@ Use the `decorate` macro to decorate methods.
141
117
 
142
118
  #### Using built-in decorators
143
119
 
144
- There are a few built-in decorators:
120
+ There are a couple of built-in decorators for common use-cases (these can be overridden if you so choose):
145
121
 
146
122
  ```rb
147
123
  class Foo
@@ -183,21 +159,25 @@ end
183
159
 
184
160
  > **Note:** in the case of multiple decorators decorating a method, each is executed from top to bottom.
185
161
 
186
- #### Using custom decorators explicitly
162
+ #### Writing custom decorators and using them _explicitly_
187
163
 
188
164
  You can reference any decorator method you write, like so:
189
165
 
190
166
  ```rb
191
167
  class FooDecorators
192
- # Note: this is a class method
168
+ # Note: this is defined as a CLASS method, but it can be applied to both class
169
+ # and instance methods. The only difference is in how you source the
170
+ # decorator when doing the decoration; see below for more info.
193
171
  def self.blast_it(context)
194
172
  puts "Blasting it!"
195
173
  value = yield
196
174
  "#{value}!"
197
175
  end
198
176
 
199
- # Note: this is an instance method
200
- def self.wait_for_it(context, dot_count: 3)
177
+ # Note: this is defined as an INSTANCE method, but it can be applied to both
178
+ # class and instance methods. The only difference is in how you source
179
+ # the decorator when doing the decoration; see below for more info.
180
+ def wait_for_it(context, dot_count: 3)
201
181
  ellipsis = dot_count.times.map { '.' }.join
202
182
  puts "Waiting for it#{ellipsis}"
203
183
  value = yield
@@ -241,23 +221,29 @@ foo.yet_another_method(123, bloop: "bleep")
241
221
  #=> "haha I'm yet another method"
242
222
  ```
243
223
 
244
- Use the `from:` option to specify what should receive the decorator method. Keep in mind that the decorator method will be called on the thing specified by `from:`... so, if you provide a class, it better be a class method, and if you supply an instance, it better be an instance method.
224
+ Use the `from:` option to specify what should receive the decorator method. Keep in mind that the decorator method will be called on the thing specified by `from:`... so, if you provide a class, it better be a class method on that thing, and if you supply an instance, it better be an instance method on that thing.
225
+
226
+ Every custom decorator method that you define must take one required argument (`context`) and any number of keyword arguments. It should also `yield` (or take a block argument and invoke it) at some point in the body of the method. The point at which you `yield` will be the point at which the decorated method will execute (or, if there are multiple decorators on the method, each following decorator will be invoked until the decorators have been exhausted and the decorated method is finally executed).
245
227
 
246
- Every custom decorator method that you define must take one required argument (`context`) and any number of keyword arguments.
228
+ ##### The required argument (`context`)
247
229
 
248
230
  The **required argument** is an instance of `Adornable::Context`, which has some useful information about the decorated method being called
249
231
 
250
- - `Adornable::Context#method_receiver`: the actual object that the [decorated] method is being called on (an object/class; e.g., `Foo` or an instance of `Foo`)
251
- - `Adornable::Context#method_name`: the name of the [decorated] method being called on `method_receiver` (a symbol; e.g., `:some_method` or `:other_method`)
252
- - `Adornable::Context#method_arguments`: an array of arguments passed to the [decorated] method, including keyword arguments as a final hash (e.g., if `:yet_another_method` was called like `Foo.new.yet_another_method(123, bar: true)` then `arguments` would be `[123, {:bar=>true}]`)
232
+ - `Adornable::Context#method_name`: the name of the decorated method being called (a symbol; e.g., `:some_method` or `:other_method`)
233
+ - `Adornable::Context#method_receiver`: the actual object that the decorated method (the `#method_name`) belongs to/is being called on (an object/class; e.g., the class `Foo` if it's a decorated class method, or an instance of `Foo` if it's a decorated instance method)
234
+ - `Adornable::Context#method_arguments`: an array of arguments passed to the decorated method, including keyword arguments as a final hash (e.g., if `:yet_another_method` was called like `Foo.new.yet_another_method(123, bar: true)` then `arguments` would be `[123, {:bar=>true}]`)
235
+
236
+ ##### Custom keyword arguments (optional)
253
237
 
254
238
  The **optional keyword arguments** are any parameters you want to be able to pass to the decorator method when decorating a method with `::decorate`:
255
239
 
256
- - If you define a decorator like `def self.some_decorator(context)` then it takes no options when it is used: `decorate :some_decorator`
257
- - If you define a decorator like `def self.some_decorator(context, some_option:)` then it takes one _required_ keyword argument when it is used: `decorate :some_decorator, some_option: 123` (`::some_decorator`, will receive `123` every time the method it's decorating is called)
258
- - Similarly, if you define a decorator like `def self.some_decorator(context, some_option: 456)`, then it takes one _optional_ keyword argument when it is used: `decorate :some_decorator` is valid (and implies `some_option: 456` since it has a default), and `decorate :some_decorator, some_option: 789` is valid as well
240
+ - If you define a decorator like `def self.some_decorator(context)` then it takes no options when it is used: `decorate :some_decorator`.
241
+ - If you define a decorator like `def self.some_decorator(context, some_option:)` then it takes one _required_ keyword argument when it is used: `decorate :some_decorator, some_option: 123` (so that `::some_decorator` will receive `123` as the `some_option` parameter every time the decorated method is called). You can customize functionality of the decorator this way.
242
+ - Similarly, if you define a decorator like `def self.some_decorator(context, some_option: 456)`, then it takes one _optional_ keyword argument when it is used: `decorate :some_decorator` is valid (and implies `some_option: 456` since it has a default), and `decorate :some_decorator, some_option: 789` is valid as well.
243
+
244
+ ##### Yielding to the next decorator/decorated method
259
245
 
260
- > **Note:** Every decorator method should _probably_ `yield` at some point in the method body. I say _"should"_ because, technically, you don't have to, but if you don't then the original method will never be called. That's a valid use-case, but 99% of the time you're gonna want to `yield`.
246
+ Every decorator method **should also probably `yield`** at some point in the method body. I say _"should"_ because, technically, you don't have to, but if you don't then the original method will never be called. That's a valid use-case, but 99% of the time you're gonna want to `yield`.
261
247
 
262
248
  > **Note:** the return value of your decorator **will replace the return value of the decorated method,** so _also_ you should probably return whatever value `yield` returned. Again, it is a valid use case to return something _else,_ but 99% of the time you probably want to return the value returned by the wrapped method.
263
249
  >
@@ -295,13 +281,12 @@ The **optional keyword arguments** are any parameters you want to be able to pas
295
281
  > #=> 123
296
282
  > ```
297
283
 
298
- #### Using custom decorators implicitly
284
+ #### Writing custom decorators and using them _implicitly_
299
285
 
300
286
  You can also register decorator receivers so that you don't have to reference them with the `from:` option:
301
287
 
302
288
  ```rb
303
289
  class FooDecorators
304
- # Note: this is a class method
305
290
  def self.blast_it(context)
306
291
  puts "Blasting it!"
307
292
  value = yield
@@ -310,8 +295,7 @@ class FooDecorators
310
295
  end
311
296
 
312
297
  class MoreFooDecorators
313
- # Note: this is a class method
314
- def self.wait_for_it(context, dot_count: 3)
298
+ def wait_for_it(context, dot_count: 3)
315
299
  ellipsis = dot_count.times.map { '.' }.join
316
300
  puts "Waiting for it#{ellipsis}"
317
301
  value = yield
@@ -323,7 +307,7 @@ class Foo
323
307
  extend Adornable
324
308
 
325
309
  add_decorators_from FooDecorators
326
- add_decorators_from MoreFooDecorators
310
+ add_decorators_from MoreFooDecorators.new
327
311
 
328
312
  decorate :blast_it
329
313
  decorate :wait_for_it, dot_count: 9
@@ -340,6 +324,8 @@ foo.some_method
340
324
  #=> "haha I'm a method!........."
341
325
  ```
342
326
 
327
+ > **Note:** All the rest of the stuff from the previous section (using decorators explicitly) also applies here (using decorators implicitly).
328
+
343
329
  > **Note:** In the case of duplicate decorator methods, later receivers registered with `::add_decorators_from` will override any decorators by the same name from earlier registered receivers.
344
330
 
345
331
  > **Note:** in the case of multiple decorators decorating a method, each is executed from top to bottom; i.e., the top wraps the next, which wraps the next, and so on, until the method itself is wrapped.
data/adornable.gemspec CHANGED
@@ -11,7 +11,7 @@ Gem::Specification.new do |spec|
11
11
  spec.email = ["kjleitz@gmail.com"]
12
12
 
13
13
  spec.summary = "Method decorators for Ruby"
14
- spec.description = "Method decorators for Ruby"
14
+ spec.description = "Adornable provides the ability to cleanly decorate methods in Ruby. You can make and use your own decorators, and you can also use some of the built-in ones that the gem provides. _Decorating_ methods is as simple as slapping a `decorate :some_decorator` above your method definition. _Defining_ decorators can be as simple as defining a method that yields to a block, or as complex as manipulating the decorated method's receiver and arguments, and/or changing the functionality of the decorator based on custom options supplied to it when initially applying the decorator."
15
15
  spec.homepage = "https://github.com/kjleitz/adornable"
16
16
  spec.license = "MIT"
17
17
  spec.required_ruby_version = ">= 2.4.7"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Adornable
4
- VERSION = "1.1.0"
4
+ VERSION = "1.1.1"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: adornable
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Keegan Leitz
@@ -122,7 +122,13 @@ dependencies:
122
122
  - - ">="
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
- description: Method decorators for Ruby
125
+ description: Adornable provides the ability to cleanly decorate methods in Ruby. You
126
+ can make and use your own decorators, and you can also use some of the built-in
127
+ ones that the gem provides. _Decorating_ methods is as simple as slapping a `decorate
128
+ :some_decorator` above your method definition. _Defining_ decorators can be as simple
129
+ as defining a method that yields to a block, or as complex as manipulating the decorated
130
+ method's receiver and arguments, and/or changing the functionality of the decorator
131
+ based on custom options supplied to it when initially applying the decorator.
126
132
  email:
127
133
  - kjleitz@gmail.com
128
134
  executables: []