nerd_dice 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
  SHA256:
3
- metadata.gz: 6c50b3a0288e78cec77247885129b370ba6d88f7a012cfefd8fceed049363487
4
- data.tar.gz: 456c3ff3d8816a567e4b80cbc49641811270483ce79cabf5fd8f4738bcd23722
3
+ metadata.gz: 8f64389429514a7d0c2a8410b2e27575e5c11b316b50cee41b37c58d8f8af953
4
+ data.tar.gz: 4d2365e3ce8139d4675695dfe47edf9ef5d52b9cc873beb5c7c314b8955aaa33
5
5
  SHA512:
6
- metadata.gz: fa26b32b8b95d4d926faa59071535b5958cc271ad190eea66a23a2fb25280c33c7d563962800a19f3f7c4947e130464450a76b8a59279b6fef9768278dbd61ec
7
- data.tar.gz: faae3546363de7437f9425f08666ba934bdb5bb4bd626e4dd3cf4c33c85147453f080c7a42cc3a9d594dc8fdb2f976aecc909261a8533f5c348fa25ee2414bdd
6
+ metadata.gz: d8bf0ea2c85e3aedf952d82d0f511463accedcad5122b14a7d6769a94100902887ca0e52cf85a6d8b69a75a6cd750858852ad71e34980e61624d39666bedff5b
7
+ data.tar.gz: ee2e8117b3071872a3d07353dabd4685c4a20e188591e80cbcb93609ba9f134ab22082ae01bee152c34c9cdd1a81a6a40aec2b1521d3e2a106d10f0c8fa313ae
checksums.yaml.gz.sig CHANGED
Binary file
@@ -14,7 +14,7 @@ jobs:
14
14
  runs-on: ubuntu-latest
15
15
  strategy:
16
16
  matrix:
17
- ruby-version: ['3.0', '3.1', '3.2']
17
+ ruby-version: ['2.7', '3.0']
18
18
 
19
19
  steps:
20
20
  - uses: actions/checkout@v2
@@ -39,7 +39,7 @@ jobs:
39
39
  - name: Set up Ruby
40
40
  uses: ruby/setup-ruby@v1
41
41
  with:
42
- ruby-version: '3.2'
42
+ ruby-version: '3.0'
43
43
  bundler-cache: true # runs 'bundle install' and caches installed gems automatically
44
44
  - name: Run rubocop
45
45
  run: bundle exec rubocop --parallel
@@ -51,7 +51,7 @@ jobs:
51
51
  - name: Set up Ruby
52
52
  uses: ruby/setup-ruby@v1
53
53
  with:
54
- ruby-version: '3.2'
54
+ ruby-version: '3.0'
55
55
  bundler-cache: true # runs 'bundle install' and caches installed gems automatically
56
56
  - name: Run benchmark script
57
57
  run: bin/nerd_dice_benchmark
data/.rubocop.yml CHANGED
@@ -1,11 +1,3 @@
1
- # RuboCop configuration file for NerdDice gem
2
- #
3
- # This is the RuboCop configuration for the gem. By default new cops are enabled
4
- # by default when the RuboCop gems are updated in the bundle. Before the would
5
- # show up as warnings until they were added to the configuration file. Now they
6
- # will be enabled by default, and a case-by-case descision can be made whether
7
- # to exclude new violations in the configuration explicitly or update the
8
- # codebase to the gem to conform to the new standard.
9
1
  require:
10
2
  - rubocop-performance
11
3
  - rubocop-rake
@@ -16,12 +8,14 @@ AllCops:
16
8
  # RuboCop has a bunch of cops enabled by default. This setting tells RuboCop
17
9
  # to ignore them, so only the ones explicitly set in this file are enabled.
18
10
  #DisabledByDefault: true
19
-
20
- # New cops are now enabled by default as of 2023-02-20
21
- NewCops: enable
22
11
  Exclude:
23
12
  - '**/templates/**/*'
24
13
  - '**/vendor/**/*'
14
+ - 'node_modules/**/*'
15
+
16
+ Performance:
17
+ Exclude:
18
+ - '**/test/**/*'
25
19
 
26
20
  # Prefer &&/|| over and/or.
27
21
  Style/AndOr:
@@ -117,6 +111,15 @@ Style/MethodDefParentheses:
117
111
  Style/FrozenStringLiteralComment:
118
112
  Enabled: true
119
113
  EnforcedStyle: always
114
+ Exclude:
115
+ - 'actionview/test/**/*.builder'
116
+ - 'actionview/test/**/*.ruby'
117
+ - 'actionpack/test/**/*.builder'
118
+ - 'actionpack/test/**/*.ruby'
119
+ - 'activestorage/db/migrate/**/*.rb'
120
+ - 'activestorage/db/update_migrate/**/*.rb'
121
+ - 'actionmailbox/db/migrate/**/*.rb'
122
+ - 'actiontext/db/migrate/**/*.rb'
120
123
 
121
124
  Style/RedundantFreeze:
122
125
  Enabled: true
@@ -188,6 +191,30 @@ Lint/UselessAssignment:
188
191
  Lint/DeprecatedClassMethods:
189
192
  Enabled: true
190
193
 
194
+ Lint/DuplicateBranch: # (new in 1.3)
195
+ Enabled: true
196
+
197
+ Lint/DuplicateRegexpCharacterClassElement: # (new in 1.1)
198
+ Enabled: true
199
+
200
+ Lint/EmptyBlock: # (new in 1.1)
201
+ Enabled: true
202
+
203
+ Lint/EmptyClass: # (new in 1.3)
204
+ Enabled: true
205
+
206
+ Lint/NoReturnInBeginEndBlocks: # (new in 1.2)
207
+ Enabled: true
208
+
209
+ Lint/ToEnumArguments: # (new in 1.1)
210
+ Enabled: true
211
+
212
+ Lint/UnexpectedBlockArity: # (new in 1.5)
213
+ Enabled: true
214
+
215
+ Lint/UnmodifiedReduceAccumulator: # (new in 1.1)
216
+ Enabled: true
217
+
191
218
  Style/ParenthesesAroundCondition:
192
219
  Enabled: true
193
220
 
@@ -209,6 +236,27 @@ Style/ColonMethodCall:
209
236
  Style/TrivialAccessors:
210
237
  Enabled: true
211
238
 
239
+ Style/ArgumentsForwarding: # (new in 1.1)
240
+ Enabled: true
241
+
242
+ Style/CollectionCompact: # (new in 1.2)
243
+ Enabled: true
244
+
245
+ Style/DocumentDynamicEvalDefinition: # (new in 1.1)
246
+ Enabled: true
247
+
248
+ Style/NegatedIfElseCondition: # (new in 1.2)
249
+ Enabled: true
250
+
251
+ Style/NilLambda: # (new in 1.3)
252
+ Enabled: true
253
+
254
+ Style/RedundantArgument: # (new in 1.4)
255
+ Enabled: true
256
+
257
+ Style/SwapValues: # (new in 1.1)
258
+ Enabled: true
259
+
212
260
  Performance/FlatMap:
213
261
  Enabled: true
214
262
 
@@ -227,9 +275,147 @@ Performance/RegexpMatch:
227
275
  Performance/UnfreezeString:
228
276
  Enabled: true
229
277
 
278
+ Performance/AncestorsInclude: # (new in 1.7)
279
+ Enabled: true
280
+
281
+ Performance/BigDecimalWithNumericArgument: # (new in 1.7)
282
+ Enabled: true
283
+
284
+ Performance/BlockGivenWithExplicitBlock: # (new in 1.9)
285
+ Enabled: true
286
+
287
+ Performance/CollectionLiteralInLoop: # (new in 1.8)
288
+ Enabled: true
289
+
290
+ Performance/ConstantRegexp: # (new in 1.9)
291
+ Enabled: true
292
+
293
+ Performance/MethodObjectAsBlock: # (new in 1.9)
294
+ Enabled: true
295
+
296
+ Performance/RedundantSortBlock: # (new in 1.7)
297
+ Enabled: true
298
+
299
+ Performance/RedundantStringChars: # (new in 1.7)
300
+ Enabled: true
301
+
302
+ Performance/ReverseFirst: # (new in 1.7)
303
+ Enabled: true
304
+
305
+ Performance/SortReverse: # (new in 1.7)
306
+ Enabled: true
307
+
308
+ Performance/Squeeze: # (new in 1.7)
309
+ Enabled: true
310
+
311
+ Performance/StringInclude: # (new in 1.7)
312
+ Enabled: true
313
+
314
+ Performance/Sum: # (new in 1.8)
315
+ Enabled: true
316
+
317
+ Layout/SpaceBeforeBrackets: # (new in 1.7)
318
+ Enabled: true
319
+
320
+ Lint/AmbiguousAssignment: # (new in 1.7)
321
+ Enabled: true
322
+
323
+ Lint/DeprecatedConstants: # (new in 1.8)
324
+ Enabled: true
325
+
326
+ Lint/LambdaWithoutLiteralBlock: # (new in 1.8)
327
+ Enabled: true
328
+
329
+ Lint/RedundantDirGlobSort: # (new in 1.8)
330
+ Enabled: true
331
+
332
+ Style/EndlessMethod: # (new in 1.8)
333
+ Enabled: true
334
+
335
+ Style/HashExcept: # (new in 1.7)
336
+ Enabled: true
337
+
338
+ # Added 2021-08-14
339
+ Gemspec/DateAssignment: # (new in 1.10)
340
+ Enabled: true
341
+
342
+ Layout/LineEndStringConcatenationIndentation: # (new in 1.18)
343
+ Enabled: true
344
+
345
+ Lint/EmptyInPattern: # (new in 1.16)
346
+ Enabled: true
347
+
348
+ Lint/NumberedParameterAssignment: # (new in 1.9)
349
+ Enabled: true
350
+
351
+ Lint/OrAssignmentToConstant: # (new in 1.9)
352
+ Enabled: true
353
+
354
+ Lint/SymbolConversion: # (new in 1.9)
355
+ Enabled: true
356
+
357
+ Lint/TripleQuotes: # (new in 1.9)
358
+ Enabled: true
359
+
360
+ Naming/InclusiveLanguage: # (new in 1.18)
361
+ Enabled: false
362
+
363
+ Style/HashConversion: # (new in 1.10)
364
+ Enabled: true
365
+
366
+ Style/IfWithBooleanLiteralBranches: # (new in 1.9)
367
+ Enabled: true
368
+
369
+ Style/InPatternThen: # (new in 1.16)
370
+ Enabled: true
371
+
372
+ Style/MultilineInPatternThen: # (new in 1.16)
373
+ Enabled: true
374
+
375
+ Style/QuotedSymbols: # (new in 1.16)
376
+ Enabled: true
377
+
378
+ Style/StringChars: # (new in 1.12)
379
+ Enabled: true
380
+
381
+ Performance/MapCompact: # (new in 1.11)
382
+ Enabled: true
383
+
384
+ Performance/RedundantEqualityComparisonBlock: # (new in 1.10)
385
+ Enabled: true
386
+
387
+ Performance/RedundantSplitRegexpArgument: # (new in 1.10)
388
+ Enabled: true
389
+
390
+ RSpec/IdenticalEqualityAssertion: # (new in 2.4)
391
+ Enabled: true
392
+
393
+ RSpec/Rails/AvoidSetupHook: # (new in 2.4)
394
+ Enabled: true
395
+
230
396
  RSpec/MessageSpies:
231
397
  EnforcedStyle: receive
232
398
 
233
- # Disable inclusive language cop. None of RuboCop's business
234
- Naming/InclusiveLanguage:
235
- Enabled: false
399
+ Lint/AmbiguousRange: # new in 1.19
400
+ Enabled: true
401
+ Style/RedundantSelfAssignmentBranch: # new in 1.19
402
+ Enabled: true
403
+
404
+ Lint/AmbiguousOperatorPrecedence: # new in 1.21
405
+ Enabled: true
406
+ Lint/IncompatibleIoSelectWithFiberScheduler: # new in 1.21
407
+ Enabled: true
408
+ Lint/RequireRelativeSelfPath: # new in 1.22
409
+ Enabled: true
410
+ Security/IoMethods: # new in 1.22
411
+ Enabled: true
412
+ Style/NumberedParameters: # new in 1.22
413
+ Enabled: true
414
+ Style/NumberedParametersLimit: # new in 1.22
415
+ Enabled: true
416
+ Style/SelectByRegexp: # new in 1.22
417
+ Enabled: true
418
+ RSpec/ExcessiveDocstringSpacing: # new in 2.5
419
+ Enabled: true
420
+ RSpec/SubjectDeclaration: # new in 2.5
421
+ Enabled: true
data/CHANGELOG.md CHANGED
@@ -1,8 +1,82 @@
1
1
  # Nerd Dice Changelog
2
2
 
3
- <img src="https://i.kym-cdn.com/photos/images/newsfeed/000/186/610/thankyou.png?1318726198" alt="Our CHANGELOG is in another castle" />
3
+ ## master \(unreleased\)
4
+ ### Added
5
+ ### Changed
6
+ ### Fixed
4
7
 
5
- ## Legacy Branch: See master
6
- This is a legacy maintenance branch.
8
+ ## 0.4.0 \(2021-10-23\)
9
+ ### Added
10
+ * Add `NerdDice::ConvenienceMethods` method_missing mixin module that allows for dynamic invocation of patterns in the method name that get converted into calls to `NerdDice.roll_dice` or `NerdDice.total_dice` along with allowing the advantage/disadvantage mechanic or bonuses to be parsed from the method name. Full documentation of the module can be found in the [Convenience Methods Mixin](README.md#convenience-methods-mixin) section of the README.
11
+ * Add exensive specs to support the ConvenienceMethods module
12
+ ### Changed
13
+ * Replace `Benchmark.bmbm` with `Benchmark.bm` in the nerd_dice_benchmark
14
+ * Add convenience_methods to nerd_dice_benchmark
15
+ * Extend `NerdDice::ConvenienceMethods` into top-level module as class methods
16
+ ### Fixed
17
+ * Fix typos and horizontal scrolling in README
18
+ * Fix CodeClimate Code Smell on harvest_totals
7
19
 
8
- The [authoritative version of the CHANGELOG](https://github.com/statelesscode/nerd_dice/blob/master/CHANGELOG.md) is found on the master branch. All other release and maintenance branches are updated to point to master after being created.
20
+ ## 0.3.0 \(2021-09-11\)
21
+ ### Added
22
+ * Add new options to `NerdDice::Configuration`
23
+ - `ability_score_number_of_sides`
24
+ - `ability_score_dice_rolled`
25
+ - `ability_score_dice_kept`
26
+ * Add `NerdDice.harvest_totals` method that takes in a collection and returns the results of calling `total` on each element
27
+ * Add `NerdDice.roll_ability_scores` convenience method that returns an array of `DiceSet` objects based on options and/or configuration
28
+ * Add `NerdDice.total_ability_scores` convenience method that returns an array of integers based on options and/or configuration
29
+ * Add `NerdDice::Die` class that represents a single die object and mixes in the `Comparable` module
30
+ * Add `NerdDice::DiceSet` class that represents a collection of `Die` objects and mixes in the `Enumerable` module
31
+ * Add `NerdDice::SetsRandomizationTechnique` mixin module and include in the `DiceSet` and `Die` classes
32
+ * Add `die_background_color` and `die_foreground_color` to `Configuration` class with defaults defined as constants
33
+ * Add `NerdDice.roll_dice` method that behaves in a similar fashion to `total_dice` but returns a `DiceSet` object instead of an `Integer` and has additional optional arguments relating to the non-numeric attributes of the dice
34
+ * Add `coveralls_reborn` to RSpec and GitHub actions
35
+ * Add build badge to README
36
+ * Add Code Climate maintainability integration and badge to README
37
+ * Add `nerd_dice_benchmark` script to bin directory
38
+ * Add GitHub Action CI build
39
+ - Run RSpec test suite, fail if specs fail, report coverage via Coveralls
40
+ - Run RuboCop and fail if violations
41
+ - Run benchmark suite and fail if outside of allowed ratios
42
+ ### Changed
43
+ * Update RuboCop version and configuration
44
+ * Break up the NerdDice source code file into several smaller files that are included by the module
45
+ * Enforce that `NerdDice.configuration.ability_score_array_size` must be a positive duck-type integer
46
+ ### Fixed
47
+
48
+ ## 0.2.0 \(2021-01-28\)
49
+ ### Added
50
+ * Add ability to configure with `NerdDice.configure` block or `NerdDice.configuration`
51
+ - Configure `randomization_technique` as `:random_rand`, `:securerandom`, `:random_object`, or `randomized`
52
+ - Configure `refresh_seed_interval` to allow a periodic refresh of the seed
53
+ * Add `randomization_technique` option to `NerdDice.total_dice` method keyword arguments
54
+ * Add a lower-level `execute_die_roll` method that allows you to roll a single die with a generator specified
55
+ * Add ability to manually refresh or specify seed with `:refresh_seed!` method
56
+ ### Changed
57
+ * Change `opts = {}` final argument to use keyword args `**opts` in the `NerdDice.total_dice` method. Now the method can be called as follows:
58
+ ```ruby
59
+ # old
60
+ NerdDice.total_dice(20, 1, {bonus: 5})
61
+ NerdDice.total_dice(6, 3, {bonus: 1})
62
+
63
+ # new
64
+ NerdDice.total_dice(20, bonus: 5)
65
+ NerdDice.total_dice(6, 3, bonus: 1)
66
+ ```
67
+ * Call `:to_i` on bonus instead of using `:is_a?` and raise ArgumentError in the `NerdDice.total_dice` method if it doesn't respond to `:to_i`
68
+ * Added `securerandom` as an explicit dependency due to Ruby 3.x change to bundled gem
69
+ * `total_dice` no longer calls unqualified `.rand` which improves performance on all generators except for `:securerandom`
70
+ ### Fixed
71
+
72
+ ## 0.1.1 \(2020-12-12\)
73
+ ### Added
74
+ ### Changed
75
+ ### Fixed
76
+ * Fix broken link to CHANGELOG in gemspec
77
+ * Fix rubocop offenses from 0.1.0 and refactor specs
78
+
79
+ ## 0.1.0 \(2020-12-07\)
80
+
81
+ ### Added
82
+ * Add NerdDice.total_dice class method with the ability to roll multiple polyhedral dice and add a bonus
data/Gemfile CHANGED
@@ -6,4 +6,4 @@ source "https://rubygems.org"
6
6
  gemspec
7
7
 
8
8
  gem "rake", "~> 13.0"
9
- gem "rspec", "~> 3.12"
9
+ gem "rspec", "~> 3.10"
data/Gemfile.lock CHANGED
@@ -1,92 +1,87 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- nerd_dice (0.3.1)
5
- securerandom (~> 0.2, >= 0.2.2)
4
+ nerd_dice (0.4.0)
5
+ securerandom (~> 0.1, >= 0.1.1)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
10
  ast (2.4.2)
11
- coveralls_reborn (0.27.0)
12
- simplecov (~> 0.22.0)
13
- term-ansicolor (~> 1.7)
14
- thor (~> 1.2)
15
- tins (~> 1.32)
16
- diff-lcs (1.5.0)
11
+ coveralls_reborn (0.23.0)
12
+ simplecov (>= 0.18.1, < 0.22.0)
13
+ term-ansicolor (~> 1.6)
14
+ thor (>= 0.20.3, < 2.0)
15
+ tins (~> 1.16)
16
+ diff-lcs (1.4.4)
17
17
  docile (1.4.0)
18
- json (2.6.3)
19
- parallel (1.22.1)
20
- parser (3.2.1.0)
18
+ parallel (1.21.0)
19
+ parser (3.0.2.0)
21
20
  ast (~> 2.4.1)
22
- rainbow (3.1.1)
21
+ rainbow (3.0.0)
23
22
  rake (13.0.6)
24
- regexp_parser (2.7.0)
23
+ regexp_parser (2.1.1)
25
24
  rexml (3.2.5)
26
- rspec (3.12.0)
27
- rspec-core (~> 3.12.0)
28
- rspec-expectations (~> 3.12.0)
29
- rspec-mocks (~> 3.12.0)
30
- rspec-core (3.12.1)
31
- rspec-support (~> 3.12.0)
32
- rspec-expectations (3.12.2)
25
+ rspec (3.10.0)
26
+ rspec-core (~> 3.10.0)
27
+ rspec-expectations (~> 3.10.0)
28
+ rspec-mocks (~> 3.10.0)
29
+ rspec-core (3.10.1)
30
+ rspec-support (~> 3.10.0)
31
+ rspec-expectations (3.10.1)
33
32
  diff-lcs (>= 1.2.0, < 2.0)
34
- rspec-support (~> 3.12.0)
35
- rspec-mocks (3.12.3)
33
+ rspec-support (~> 3.10.0)
34
+ rspec-mocks (3.10.2)
36
35
  diff-lcs (>= 1.2.0, < 2.0)
37
- rspec-support (~> 3.12.0)
38
- rspec-support (3.12.0)
39
- rubocop (1.46.0)
40
- json (~> 2.3)
36
+ rspec-support (~> 3.10.0)
37
+ rspec-support (3.10.2)
38
+ rubocop (1.22.2)
41
39
  parallel (~> 1.10)
42
- parser (>= 3.2.0.0)
40
+ parser (>= 3.0.0.0)
43
41
  rainbow (>= 2.2.2, < 4.0)
44
42
  regexp_parser (>= 1.8, < 3.0)
45
- rexml (>= 3.2.5, < 4.0)
46
- rubocop-ast (>= 1.26.0, < 2.0)
43
+ rexml
44
+ rubocop-ast (>= 1.12.0, < 2.0)
47
45
  ruby-progressbar (~> 1.7)
48
- unicode-display_width (>= 2.4.0, < 3.0)
49
- rubocop-ast (1.26.0)
50
- parser (>= 3.2.1.0)
51
- rubocop-capybara (2.17.1)
52
- rubocop (~> 1.41)
53
- rubocop-performance (1.16.0)
46
+ unicode-display_width (>= 1.4.0, < 3.0)
47
+ rubocop-ast (1.12.0)
48
+ parser (>= 3.0.1.1)
49
+ rubocop-performance (1.11.5)
54
50
  rubocop (>= 1.7.0, < 2.0)
55
51
  rubocop-ast (>= 0.4.0)
56
52
  rubocop-rake (0.6.0)
57
53
  rubocop (~> 1.0)
58
- rubocop-rspec (2.18.1)
59
- rubocop (~> 1.33)
60
- rubocop-capybara (~> 2.17)
54
+ rubocop-rspec (2.5.0)
55
+ rubocop (~> 1.19)
61
56
  ruby-progressbar (1.11.0)
62
- securerandom (0.2.2)
63
- simplecov (0.22.0)
57
+ securerandom (0.1.1)
58
+ simplecov (0.21.2)
64
59
  docile (~> 1.1)
65
60
  simplecov-html (~> 0.11)
66
61
  simplecov_json_formatter (~> 0.1)
67
62
  simplecov-html (0.12.3)
68
63
  simplecov-lcov (0.8.0)
69
- simplecov_json_formatter (0.1.4)
64
+ simplecov_json_formatter (0.1.3)
70
65
  sync (0.5.0)
71
66
  term-ansicolor (1.7.1)
72
67
  tins (~> 1.0)
73
- thor (1.2.1)
74
- tins (1.32.1)
68
+ thor (1.1.0)
69
+ tins (1.29.1)
75
70
  sync
76
- unicode-display_width (2.4.2)
71
+ unicode-display_width (2.1.0)
77
72
 
78
73
  PLATFORMS
79
74
  ruby
80
75
 
81
76
  DEPENDENCIES
82
- coveralls_reborn (~> 0.27.0)
77
+ coveralls_reborn (~> 0.23.0)
83
78
  nerd_dice!
84
79
  rake (~> 13.0)
85
- rspec (~> 3.12)
86
- rubocop (~> 1.46, >= 1.46.0)
87
- rubocop-performance (~> 1.16, >= 1.16.0)
80
+ rspec (~> 3.10)
81
+ rubocop (~> 1.22, >= 1.22.2)
82
+ rubocop-performance (~> 1.11, >= 1.11.5)
88
83
  rubocop-rake (~> 0.6, >= 0.6.0)
89
- rubocop-rspec (~> 2.18, >= 2.18.1)
84
+ rubocop-rspec (~> 2.5, >= 2.5.0)
90
85
  simplecov-lcov (~> 0.8.0)
91
86
 
92
87
  BUNDLED WITH
data/README.md CHANGED
@@ -24,6 +24,15 @@ Or install it yourself as:
24
24
  $ gem install nerd_dice
25
25
 
26
26
  ## Usage
27
+ After the gem is installed, you can require it as you would any other gem.
28
+
29
+ ```ruby
30
+ require 'nerd_dice'
31
+ ```
32
+
33
+ ### Module methods or a dynamic method_missing DSL
34
+ There are two main patterns for using NerdDice in your project. You can invoke the module-level methods like `NerdDice.total_dice` or you can include the `NerdDice::ConvenienceMethods` module to your class \(or IRB \). Once mixed in, you can dynamically invoke methods like `roll_d20_with_advantage` or `total_3d8_plus5`. See the [Convenience Methods Mixin](#convenience-methods-mixin) section for usage details.
35
+
27
36
  ### Configuration
28
37
  You can customize the behavior of NerdDice via a configuration block as below or by assigning an individual property via the ```NerdDice.configuration.property = value``` syntax \(where ```property``` is the config property and ```value``` is the value you want to assign\)\. The available configuration options as well as their defaults, if applicable, are listed in the example configuration block below:
29
38
 
@@ -268,6 +277,126 @@ totals_array = NerdDice.harvest_totals(totals_array)
268
277
  # => [15, 14, 13, 12, 10, 8]
269
278
  # yes, it just happened to be the standard array by amazing coincidence
270
279
  ```
280
+ <a name="convenience-methods-mixin"></a>
281
+ ### Convenience Methods Mixin
282
+ NerdDice provides an optional mixin `NerdDice::ConvenienceMethods` that uses Ruby\'s `method_missing` metaprogramming pattern to allow you to roll any number of dice with bonuses and/or the advantage/disadvantage mechanic by dynamically responding to methods that you type that match the `roll_` or `total_` pattern.
283
+
284
+ #### Considerations for ConvenienceMethods
285
+ Before mixing in this method with a class, be aware of other `method_missing` gems that you are also mixing into your project and be sure to write robust tests. We have sought to use `method_missing` in a responsible manner that delegates back to the default implementation using `super` if the method does not match the `ConvenienceMethods` pattern, but there is no guarantee that other gems included in your project are doing the same. If you run into problems with the `ConvenienceMethods` module interacting with other `method_missing` gems, everything that the `ConvenienceMethods` module does can be replicated using the module\-level methods described above or by calling the convenience method on `NerdDice`.
286
+
287
+ Once a particular method has been called, it will define that method so that the next time it will invoke the method directly instead of traversing up the call stack for `method_missing`, which improves performance. The method will remain defined for the duration of the Ruby interpreter process.
288
+
289
+ #### Calling ConvenienceMethods as NerdDice class methods
290
+ NerdDice extends the `ConvenienceMethods` module into the top-level module as class methods, so you can call the methods on the NerdDice module without needing to worry about the implications of extending it into your own class.
291
+ ```ruby
292
+ require 'nerd_dice'
293
+ # works with all the examples and patterns below
294
+ NerdDice.roll_3d6_lowest2_minus1
295
+ NerdDice.total_d20_with_advantage_p6
296
+ ```
297
+
298
+ #### Mixing in the ConvenienceMethods module
299
+ To mix the NerdDice DSL into your class, make sure the gem is required if not already and then use `include NerdDice::ConvenienceMethods` as shown below:
300
+ ```ruby
301
+ # example of a class that mixes in NerdDice::ConvenienceMethods
302
+ require 'nerd_dice'
303
+ class Monster
304
+ include NerdDice::ConvenienceMethods
305
+
306
+ # hard-coding probably not the best solution
307
+ # but gives you an idea how to mix in to a simple class
308
+ def hits_the_monster
309
+ # using the ConvenienceMethods version
310
+ total_d20_plus5 >= @armor_class ? "hit" : "miss"
311
+ end
312
+
313
+ def initialize(armor_class=16)
314
+ @armor_class = armor_class
315
+ end
316
+ end
317
+ ```
318
+ To mix in the module as class methods, you can use `extend NerdDice::ConvenienceMethods`
319
+ ```ruby
320
+ # example of a class that mixes in NerdDice::ConvenienceMethods
321
+ require 'nerd_dice'
322
+ class OtherClass
323
+ extend NerdDice::ConvenienceMethods
324
+ end
325
+ OtherClass.roll_3d6_lowest2_minus1 # returns NerdDice::DiceSet
326
+ ```
327
+
328
+ #### ConvenienceMethods usage examples
329
+ Any invocation of `NerdDice.roll_dice` and `NerdDice.total_dice` can be duplicated using the `NerdDice::ConvenienceMethods` mixin. Here are some examples of what you can do with the return types and equivalent methods in the comments:
330
+
331
+ * `roll_dNN` and `total_dNN` roll one die
332
+ ```ruby
333
+ roll_d20 # => DiceSet: NerdDice.roll_dice(20)
334
+ roll_d8 # => DiceSet: NerdDice.roll_dice(8)
335
+ roll_d1000 # => DiceSet: NerdDice.roll_dice(1000)
336
+ total_d20 # => Integer NerdDice.total_dice(20)
337
+ total_d8 # => Integer NerdDice.total_dice(8)
338
+ total_d1000 # => Integer NerdDice.total_dice(1000)
339
+ ```
340
+ * `roll_NNdNN` and `total_NNdNN` roll specified quantity of dice
341
+ ```ruby
342
+ roll_2d20 # => DiceSet: NerdDice.roll_dice(20, 2)
343
+ roll_3d8 # => DiceSet: NerdDice.roll_dice(8, 3)
344
+ roll_22d1000 # => DiceSet: NerdDice.roll_dice(1000, 22)
345
+ total_2d20 # => Integer NerdDice.total_dice(20, 2)
346
+ total_3d8 # => Integer NerdDice.total_dice(8, 3)
347
+ total_22d1000 # => Integer NerdDice.total_dice(1000, 22)
348
+ ```
349
+ * Keyword arguments are passed on to `roll_dice`/`total_dice` method
350
+ ```ruby
351
+ roll_2d20 foreground_color: "blue" # => DiceSet: NerdDice.roll_dice(20, 2, foreground_color: "blue")
352
+
353
+ total_d12 randomization_technique: :randomized
354
+ # => Integer NerdDice.total_dice(12, randomization_technique: :randomized)
355
+ total_22d1000 randomization_technique: :random_rand
356
+ # => Integer NerdDice.total_dice(1000, 22, randomization_technique: :random_rand)
357
+
358
+ roll_4d6_with_advantage3 background_color: 'blue'
359
+ # => DiceSet: NerdDice.roll_dice(4, 3, background_color: 'blue').highest(3)
360
+ total_4d6_with_advantage3 randomization_technique: :random_rand
361
+ # => Integer: NerdDice.roll_dice(4, 3, randomization_technique: :random_rand).highest(3).total
362
+ ```
363
+ * Positive and negative bonuses can be used with `plus` (alias `p`) or `minus` (alias `m`)
364
+ ```ruby
365
+ roll_d20_plus6 # => DiceSet: NerdDice.roll_dice(20, bonus: 6)
366
+ total_3d8_p2 # => Integer: NerdDice.total_dice(8, 3, bonus: 2)
367
+ total_d20_minus5 # => Integer: NerdDice.total_dice(20, bonus: -6)
368
+ roll_3d8_m3 # => DiceSet: NerdDice.roll_dice(8, 3, bonus: -3)
369
+ ```
370
+ * `_with_advantageN` or `highestN` roll with advantage
371
+ * `_with_disadvantageN` or `lowestN` roll with disadvantage
372
+ * Calling `roll_dNN_with_advantage` \(and variants\) rolls 2 dice and keeps one
373
+ ```ruby
374
+ # equivalent
375
+ roll_3d8_with_advantage1
376
+ roll_3d8_highest1
377
+ # => DiceSet: NerdDice.roll_dice(8, 3).with_advantage(1)
378
+
379
+ # calls roll_dice and total to return an integer
380
+ total_3d8_with_advantage1
381
+ total_3d8_highest1
382
+ # => Integer: NerdDice.roll_dice(8, 3).with_advantage(1).total
383
+
384
+ # rolls two dice in this case
385
+ # equal to roll_2d20_with_advantage but more natural
386
+ roll_d20_with_advantage # => DiceSet: NerdDice.roll_dice(20, 2).with_advantage(1)
387
+ # equal to total_2d20_with_advantage but more natural
388
+ total_d20_with_advantage # => Integer: NerdDice.roll_dice(20, 2).with_advantage(1).total
389
+ ```
390
+ #### ConvenienceMethods error handling
391
+ * If you try to call with a plus and a minus, an Exception is raised
392
+ * If you call with a bonus and a keyword argument and they don't match, an Exception is raised
393
+ * Any combination not expressly allowed or matched will call `super` on `method_missing`
394
+ ```ruby
395
+ roll_3d8_plus3_m2 # will raise NameError using super method_missing
396
+ roll_3d8_plus3 bonus: 1 # will raise NerdDice::Error with message about "Bonus integrity failure"
397
+ roll_d20_with_advantage_lowest # will raise NameError using super method_missing
398
+ total_4d6_lowest3_highest2 # will raise NameError using super method_missing
399
+ ```
271
400
 
272
401
  ## Development
273
402
 
@@ -277,7 +406,8 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
277
406
 
278
407
  ## Contributing
279
408
 
280
- Bug reports and pull requests are welcome on GitHub at https://github.com/statelesscode/nerd_dice/issues. We welcome and encourage your participation in this open-source project. We welcome those of all backgrounds and abilities, but we refuse to adopt the Contributor Covenant for reasons outlined in [BURN_THE_CONTRIBUTOR_COVENANT_WITH_FIRE.md](BURN_THE_CONTRIBUTOR_COVENANT_WITH_FIRE.md)
409
+ Bug reports and pull requests are welcome on GitHub at https://github.com/statelesscode/nerd_dice/issues. We welcome and encourage your participation in this open-source project. We welcome those of all backgrounds and abilities, but we refuse to adopt the Contributor Covenant for reasons outlined in [BURN_THE_CONTRIBUTOR_COVENANT_WITH_FIRE.md](https://github.com/statelesscode/nerd_dice/blob/master/BURN_THE_CONTRIBUTOR_COVENANT_WITH_FIRE.md)
410
+
281
411
 
282
412
  ## Unlicense, License, and Copyright
283
413