initable 0.2.0 → 0.3.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: 96778d9b0314485a1c240e2c5ef7867df42092d4f906e794ec54097de2c6de93
4
- data.tar.gz: 6b3619194eb1d9767e80ad31e13a7037fe10542c7b497a14df77ad7f04dade71
3
+ metadata.gz: 2daf64cfb3c191bbde13cf2df0906dc5eb61a53b5692d81759a04377574dbd47
4
+ data.tar.gz: 05f51e03305374baef88f4c316ab076fccae03440da452e94bd2a65b728e79f7
5
5
  SHA512:
6
- metadata.gz: ddabf5ef26a500fd501f59a89a6a7dc370b00136206737a14f534ee72fb7dce5ce58848b7c03985952c66212e6d53cfa1ce8882acefd7d36ca23befb1f070acc
7
- data.tar.gz: 65e7d06a70d8f00f24b5b3edc7b4ccaf6672e7a357533c38991f7f4ea1619c5a9411b673f26d95444ba5530642e03c1ed0a339d4eeba2bdd47091e4cd7c1252c
6
+ metadata.gz: 8a39dd5abf3ac374ca96b1bcb6debe1445116a868afc5f5e36634cc50beac663cc8fd949983b5f51a21127bb518b10151ba27cf192bdb7a8ccd0893fab585d1c
7
+ data.tar.gz: 30ce0f75f840e2536219f51dc1011974ce86b2855331d94117c08d1a5fc75039ce5606f3f99d741f6882ccb6ec3d7d641d0eccc4629c0328f5a298c712034337
checksums.yaml.gz.sig CHANGED
Binary file
data/README.adoc CHANGED
@@ -129,7 +129,7 @@ There are eight _kinds_ of parameters you can use in method signatures as suppor
129
129
  [<kind>, <name>, <default>]
130
130
  ----
131
131
 
132
- 💡 The default (third element) is always optional which, granted, isn't supported by {method_parameters_link} but is part of this DSL so you can supply a default value for optional positional or keyword parameters with minimal effort.
132
+ 💡 The default (third element) is always optional and isn't supported by {method_parameters_link} but is part of this DSL so you can supply a default value for optional positional or keyword parameters with minimal effort.
133
133
 
134
134
  As detailed in the {method_parameters_and_arguments_link} article, the order of each kind of parameter matters because if you define them out of order, you'll get a syntax error as you would get when not using this gem to initialize an object. For reference, here's the natural order of parameters for a method signature in case it helps:
135
135
 
@@ -316,6 +316,45 @@ end
316
316
 
317
317
  This is useful when needing to forward a block to the super class.
318
318
 
319
+ === Keywords
320
+
321
+ As an added convenience, you can use keywords in addition to positional arguments when initializing your class. Example:
322
+
323
+ [source,ruby]
324
+ ----
325
+ demo = Class.new do
326
+ include Initable[one: 1, two: 2]
327
+ end
328
+
329
+ demo.new #<#<Class:0x0000000135753678>:0x0000000136091f00 @one=1, @two=2>
330
+ ----
331
+
332
+ The above is identical to the following but with less typing:
333
+
334
+ [source,ruby]
335
+ ----
336
+ demo = Class.new do
337
+ include Initable[[:key, :one, 1], [:key, :two, 2]]
338
+ end
339
+
340
+ demo.new #<#<Class:0x0000000136f1ef78>:0x00000001518775b0 @one=1, @two=2>
341
+ ----
342
+
343
+ You can also combine positionals with keywords:
344
+
345
+ [source,ruby]
346
+ ----
347
+ demo = Class.new do
348
+ include Initable[%i[req one], [:key, :two, 2], three: 3]
349
+ end
350
+
351
+ demo.new 1 # #<#<Class:0x0000000136ede9c8>:0x0000000151ebab98 @one=1, @two=2, @three=3>
352
+ ----
353
+
354
+ ⚠️ As with default `+#initialize+` implementations, ensure you don't duplicate parameter names to avoid naming collisions.
355
+
356
+ In most cases, you'll want to use xref:_parameters[Parameters] as documented earlier. Otherwise, this is a nice way to initialize with safe defaults or utilize lightweight dependency injection without having to reach for {infusible_link} when you don't need a full fledged {containable_link} container.
357
+
319
358
  === Defaults
320
359
 
321
360
  You've already seen you can provide a third element for defaults with optional positional and keyword parameters. Sometimes, though, you might want to use a more complex object as a default (especially if you want the default to be lazy loaded/initialized). For those situations use a `Proc`. Example:
@@ -325,12 +364,17 @@ You've already seen you can provide a third element for defaults with optional p
325
364
  demo = Class.new do
326
365
  include Initable[
327
366
  [:opt, :one, proc { %w[O n e].join }],
328
- [:key, :two, proc { Object.new }]
367
+ [:key, :two, proc { Object.new }],
368
+ three: proc { StringIO.new }
329
369
  ]
330
370
  end
331
371
 
332
372
  demo.new
333
- #<#<Class:0x00000001532d4390>:0x0000000153a9b0b0 @one="One", @two=#<Object:0x0000000153a9ade0>>
373
+ # <#<Class:0x00000001532d4390>:0x0000000153a9b0b0
374
+ # @one="One",
375
+ # @two=#<Object:0x000000012f89b108>,
376
+ # @three=#<StringIO:0x000000012fe361f8>
377
+ # >
334
378
  ----
335
379
 
336
380
  Notice, for the `one` optional positional parameter, we get a default value of `"One"` once evaluated. For the `two` optional keyword parameter, we get a new instance of `Object` as a default value.
@@ -340,6 +384,7 @@ Notice, for the `one` optional positional parameter, we get a default value of `
340
384
  * Use procs because lambdas will throw a `TypeError`.
341
385
  * Use procs _with no arguments_ because only the body of the `Proc` is parsed. Otherwise, you'll get an `ArgumentError`.
342
386
  * Ensure each parameter -- with a default -- is defined on a distinct line because the body of the `Proc` is extracted at runtime from the source location of the `Proc`. The goal is to improve upon this further once Ruby link:https://bugs.ruby-lang.org/issues/21005[adds] source location with line start, line end, column start, and column end information.
387
+ * This does not work consistently in IRB due to the above mentioned Ruby issue.
343
388
 
344
389
  === Barewords
345
390
 
data/initable.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = "initable"
5
- spec.version = "0.2.0"
5
+ spec.version = "0.3.0"
6
6
  spec.authors = ["Brooke Kuhlmann"]
7
7
  spec.email = ["brooke@alchemists.io"]
8
8
  spec.homepage = "https://alchemists.io/projects/initable"
@@ -4,14 +4,13 @@ require "marameters"
4
4
 
5
5
  module Initable
6
6
  # Builds initialization behavior.
7
- # :reek:TooManyInstanceVariables
8
7
  class Builder < Module
9
- def initialize *parameters, scope: :private, marameters: Marameters
8
+ def initialize *parameters, method_scope: :private, **keywords
10
9
  super()
10
+ keywords.each { |key, value| parameters.push [:key, key, value] }
11
11
 
12
- @parameters = marameters.for parameters
13
- @scope = scope
14
- @marameters = marameters
12
+ @parameters = Marameters.for parameters
13
+ @method_scope = method_scope
15
14
  @names = @parameters.names.compact
16
15
  @instance_module = Module.new.set_temporary_name "initable"
17
16
 
@@ -26,18 +25,18 @@ module Initable
26
25
 
27
26
  private
28
27
 
29
- attr_reader :scope, :parameters, :marameters, :names, :instance_module
28
+ attr_reader :method_scope, :parameters, :names, :instance_module
30
29
 
31
30
  def define_initialize descendant,
32
31
  inheritor: Marameters::Signatures::Inheritor.new,
33
32
  forwarder: Marameters::Signatures::Super.new
34
- ancestor = marameters.of(descendant, :initialize).first
35
- signature = inheritor.call(ancestor, parameters).then { |params| marameters.signature params }
33
+ ancestor = Marameters.of(descendant, :initialize).first
34
+ signature = inheritor.call(ancestor, parameters).then { |params| Marameters.signature params }
36
35
 
37
36
  instance_module.module_eval <<-METHOD, __FILE__, __LINE__ + 1
38
37
  def initialize(#{signature})
39
- super(#{forwarder.call ancestor, parameters})
40
38
  #{build_instance_variables ancestor}
39
+ super(#{forwarder.call ancestor, parameters})
41
40
  end
42
41
  METHOD
43
42
 
@@ -55,6 +54,6 @@ module Initable
55
54
  READERS
56
55
  end
57
56
 
58
- def compute_scope = METHOD_SCOPES.include?(scope) ? scope : :private
57
+ def compute_scope = METHOD_SCOPES.include?(method_scope) ? method_scope : :private
59
58
  end
60
59
  end
data/lib/initable.rb CHANGED
@@ -6,9 +6,9 @@ require "initable/builder"
6
6
  module Initable
7
7
  METHOD_SCOPES = %i[public protected private].freeze
8
8
 
9
- def self.[](*) = Builder.new(*)
9
+ def self.[](*, **) = Builder.new(*, **)
10
10
 
11
- def self.protected(*) = Builder.new(*, scope: __method__)
11
+ def self.protected(*, **) = Builder.new(*, method_scope: __method__, **)
12
12
 
13
- def self.public(*) = Builder.new(*, scope: __method__)
13
+ def self.public(*, **) = Builder.new(*, method_scope: __method__, **)
14
14
  end
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: initable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brooke Kuhlmann
@@ -34,7 +34,7 @@ cert_chain:
34
34
  3n5C8/6Zh9DYTkpcwPSuIfAga6wf4nXc9m6JAw8AuMLaiWN/r/2s4zJsUHYERJEu
35
35
  gZGm4JqtuSg8pYjPeIJxS960owq+SfuC+jxqmRA54BisFCv/0VOJi7tiJVY=
36
36
  -----END CERTIFICATE-----
37
- date: 2025-02-05 00:00:00.000000000 Z
37
+ date: 2025-03-14 00:00:00.000000000 Z
38
38
  dependencies:
39
39
  - !ruby/object:Gem::Dependency
40
40
  name: marameters
@@ -88,7 +88,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
88
88
  - !ruby/object:Gem::Version
89
89
  version: '0'
90
90
  requirements: []
91
- rubygems_version: 3.6.3
91
+ rubygems_version: 3.6.6
92
92
  specification_version: 4
93
93
  summary: An automatic object initializer.
94
94
  test_files: []
metadata.gz.sig CHANGED
Binary file