dry-initializer 3.0.3 → 3.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +234 -242
- data/dry-initializer.gemspec +28 -15
- data/lib/dry/initializer/builders/attribute.rb +1 -1
- data/lib/dry/initializer/version.rb +1 -1
- metadata +24 -104
- data/.codeclimate.yml +0 -12
- data/.github/ISSUE_TEMPLATE/----please-don-t-ask-for-support-via-issues.md +0 -10
- data/.github/ISSUE_TEMPLATE/---bug-report.md +0 -30
- data/.github/ISSUE_TEMPLATE/---feature-request.md +0 -18
- data/.github/workflows/custom_ci.yml +0 -58
- data/.github/workflows/docsite.yml +0 -34
- data/.github/workflows/sync_configs.yml +0 -56
- data/.gitignore +0 -12
- data/.rspec +0 -4
- data/.rubocop.yml +0 -102
- data/CODE_OF_CONDUCT.md +0 -13
- data/CONTRIBUTING.md +0 -29
- data/Gemfile +0 -36
- data/Gemfile.devtools +0 -16
- data/Guardfile +0 -5
- data/LICENSE.txt +0 -21
- data/Rakefile +0 -8
- data/benchmarks/compare_several_defaults.rb +0 -82
- data/benchmarks/plain_options.rb +0 -63
- data/benchmarks/plain_params.rb +0 -84
- data/benchmarks/with_coercion.rb +0 -71
- data/benchmarks/with_defaults.rb +0 -66
- data/benchmarks/with_defaults_and_coercion.rb +0 -59
- data/bin/.gitkeep +0 -0
- data/docsite/source/attributes.html.md +0 -106
- data/docsite/source/container-version.html.md +0 -39
- data/docsite/source/index.html.md +0 -43
- data/docsite/source/inheritance.html.md +0 -43
- data/docsite/source/optionals-and-defaults.html.md +0 -130
- data/docsite/source/options-tolerance.html.md +0 -27
- data/docsite/source/params-and-options.html.md +0 -74
- data/docsite/source/rails-support.html.md +0 -101
- data/docsite/source/readers.html.md +0 -43
- data/docsite/source/skip-undefined.html.md +0 -59
- data/docsite/source/type-constraints.html.md +0 -160
- data/project.yml +0 -2
- data/spec/attributes_spec.rb +0 -38
- data/spec/coercion_of_nil_spec.rb +0 -25
- data/spec/custom_dispatchers_spec.rb +0 -35
- data/spec/custom_initializer_spec.rb +0 -30
- data/spec/default_values_spec.rb +0 -83
- data/spec/definition_spec.rb +0 -111
- data/spec/invalid_default_spec.rb +0 -13
- data/spec/list_type_spec.rb +0 -32
- data/spec/missed_default_spec.rb +0 -14
- data/spec/nested_type_spec.rb +0 -48
- data/spec/optional_spec.rb +0 -71
- data/spec/options_tolerance_spec.rb +0 -11
- data/spec/public_attributes_utility_spec.rb +0 -22
- data/spec/reader_spec.rb +0 -87
- data/spec/repetitive_definitions_spec.rb +0 -69
- data/spec/several_assignments_spec.rb +0 -41
- data/spec/spec_helper.rb +0 -24
- data/spec/subclassing_spec.rb +0 -49
- data/spec/support/coverage.rb +0 -7
- data/spec/support/warnings.rb +0 -7
- data/spec/type_argument_spec.rb +0 -35
- data/spec/type_constraint_spec.rb +0 -96
- data/spec/value_coercion_via_dry_types_spec.rb +0 -29
data/benchmarks/with_coercion.rb
DELETED
@@ -1,71 +0,0 @@
|
|
1
|
-
Bundler.require(:benchmarks)
|
2
|
-
|
3
|
-
require 'dry-initializer'
|
4
|
-
class DryTest
|
5
|
-
extend Dry::Initializer[undefined: false]
|
6
|
-
|
7
|
-
option :foo, proc(&:to_s)
|
8
|
-
option :bar, proc(&:to_s)
|
9
|
-
end
|
10
|
-
|
11
|
-
class DryTestUndefined
|
12
|
-
extend Dry::Initializer
|
13
|
-
|
14
|
-
option :foo, proc(&:to_s)
|
15
|
-
option :bar, proc(&:to_s)
|
16
|
-
end
|
17
|
-
|
18
|
-
class PlainRubyTest
|
19
|
-
attr_reader :foo, :bar
|
20
|
-
|
21
|
-
def initialize(options)
|
22
|
-
@foo = options[:foo].to_s
|
23
|
-
@bar = options[:bar].to_s
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
require 'virtus'
|
28
|
-
class VirtusTest
|
29
|
-
include Virtus.model
|
30
|
-
|
31
|
-
attribute :foo, String
|
32
|
-
attribute :bar, String
|
33
|
-
end
|
34
|
-
|
35
|
-
require 'fast_attributes'
|
36
|
-
class FastAttributesTest
|
37
|
-
extend FastAttributes
|
38
|
-
|
39
|
-
define_attributes initialize: true do
|
40
|
-
attribute :foo, String
|
41
|
-
attribute :bar, String
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
puts 'Benchmark for instantiation with coercion'
|
46
|
-
|
47
|
-
Benchmark.ips do |x|
|
48
|
-
x.config time: 15, warmup: 10
|
49
|
-
|
50
|
-
x.report('plain Ruby') do
|
51
|
-
PlainRubyTest.new foo: 'FOO', bar: 'BAR'
|
52
|
-
end
|
53
|
-
|
54
|
-
x.report('dry-initializer') do
|
55
|
-
DryTest.new foo: 'FOO', bar: 'BAR'
|
56
|
-
end
|
57
|
-
|
58
|
-
x.report('dry-initializer (with UNDEFINED)') do
|
59
|
-
DryTestUndefined.new foo: 'FOO', bar: 'BAR'
|
60
|
-
end
|
61
|
-
|
62
|
-
x.report('virtus') do
|
63
|
-
VirtusTest.new foo: 'FOO', bar: 'BAR'
|
64
|
-
end
|
65
|
-
|
66
|
-
x.report('fast_attributes') do
|
67
|
-
FastAttributesTest.new foo: 'FOO', bar: 'BAR'
|
68
|
-
end
|
69
|
-
|
70
|
-
x.compare!
|
71
|
-
end
|
data/benchmarks/with_defaults.rb
DELETED
@@ -1,66 +0,0 @@
|
|
1
|
-
Bundler.require(:benchmarks)
|
2
|
-
|
3
|
-
require 'dry-initializer'
|
4
|
-
class DryTest
|
5
|
-
extend Dry::Initializer[undefined: false]
|
6
|
-
|
7
|
-
option :foo, default: -> { 'FOO' }
|
8
|
-
option :bar, default: -> { 'BAR' }
|
9
|
-
end
|
10
|
-
|
11
|
-
class DryTestUndefined
|
12
|
-
extend Dry::Initializer
|
13
|
-
|
14
|
-
option :foo, default: -> { 'FOO' }
|
15
|
-
option :bar, default: -> { 'BAR' }
|
16
|
-
end
|
17
|
-
|
18
|
-
class PlainRubyTest
|
19
|
-
attr_reader :foo, :bar
|
20
|
-
|
21
|
-
def initialize(foo: 'FOO', bar: 'BAR')
|
22
|
-
@foo = foo
|
23
|
-
@bar = bar
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
require 'kwattr'
|
28
|
-
class KwattrTest
|
29
|
-
kwattr foo: 'FOO', bar: 'BAR'
|
30
|
-
end
|
31
|
-
|
32
|
-
require 'active_attr'
|
33
|
-
class ActiveAttrTest
|
34
|
-
include ActiveAttr::AttributeDefaults
|
35
|
-
|
36
|
-
attribute :foo, default: 'FOO'
|
37
|
-
attribute :bar, default: 'BAR'
|
38
|
-
end
|
39
|
-
|
40
|
-
puts 'Benchmark for instantiation with default values'
|
41
|
-
|
42
|
-
Benchmark.ips do |x|
|
43
|
-
x.config time: 15, warmup: 10
|
44
|
-
|
45
|
-
x.report('plain Ruby') do
|
46
|
-
PlainRubyTest.new
|
47
|
-
end
|
48
|
-
|
49
|
-
x.report('dry-initializer') do
|
50
|
-
DryTest.new
|
51
|
-
end
|
52
|
-
|
53
|
-
x.report('dry-initializer (with UNDEFINED)') do
|
54
|
-
DryTestUndefined.new
|
55
|
-
end
|
56
|
-
|
57
|
-
x.report('kwattr') do
|
58
|
-
KwattrTest.new
|
59
|
-
end
|
60
|
-
|
61
|
-
x.report('active_attr') do
|
62
|
-
ActiveAttrTest.new
|
63
|
-
end
|
64
|
-
|
65
|
-
x.compare!
|
66
|
-
end
|
@@ -1,59 +0,0 @@
|
|
1
|
-
Bundler.require(:benchmarks)
|
2
|
-
|
3
|
-
require 'dry-initializer'
|
4
|
-
class DryTest
|
5
|
-
extend Dry::Initializer[undefined: false]
|
6
|
-
|
7
|
-
option :foo, proc(&:to_s), default: -> { 'FOO' }
|
8
|
-
option :bar, proc(&:to_s), default: -> { 'BAR' }
|
9
|
-
end
|
10
|
-
|
11
|
-
class DryTestUndefined
|
12
|
-
extend Dry::Initializer
|
13
|
-
|
14
|
-
option :foo, proc(&:to_s), default: -> { 'FOO' }
|
15
|
-
option :bar, proc(&:to_s), default: -> { 'BAR' }
|
16
|
-
end
|
17
|
-
|
18
|
-
class PlainRubyTest
|
19
|
-
attr_reader :foo, :bar
|
20
|
-
|
21
|
-
def initialize(foo: 'FOO', bar: 'BAR')
|
22
|
-
@foo = foo
|
23
|
-
@bar = bar
|
24
|
-
raise TypeError unless String === @foo
|
25
|
-
raise TypeError unless String === @bar
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
require 'virtus'
|
30
|
-
class VirtusTest
|
31
|
-
include Virtus.model
|
32
|
-
|
33
|
-
attribute :foo, String, default: 'FOO'
|
34
|
-
attribute :bar, String, default: 'BAR'
|
35
|
-
end
|
36
|
-
|
37
|
-
puts 'Benchmark for instantiation with type constraints and default values'
|
38
|
-
|
39
|
-
Benchmark.ips do |x|
|
40
|
-
x.config time: 15, warmup: 10
|
41
|
-
|
42
|
-
x.report('plain Ruby') do
|
43
|
-
PlainRubyTest.new
|
44
|
-
end
|
45
|
-
|
46
|
-
x.report('dry-initializer') do
|
47
|
-
DryTest.new
|
48
|
-
end
|
49
|
-
|
50
|
-
x.report('dry-initializer (with UNDEFINED)') do
|
51
|
-
DryTest.new
|
52
|
-
end
|
53
|
-
|
54
|
-
x.report('virtus') do
|
55
|
-
VirtusTest.new
|
56
|
-
end
|
57
|
-
|
58
|
-
x.compare!
|
59
|
-
end
|
data/bin/.gitkeep
DELETED
File without changes
|
@@ -1,106 +0,0 @@
|
|
1
|
-
---
|
2
|
-
title: Attributes
|
3
|
-
layout: gem-single
|
4
|
-
name: dry-initializer
|
5
|
-
---
|
6
|
-
|
7
|
-
Sometimes you need to access all attributes assigned via params and options of the object constructor.
|
8
|
-
|
9
|
-
We support 2 methods: `attributes` and `public_attributes` for this goal. Both methods are wrapped into container accessible via `.dry_types` container:
|
10
|
-
|
11
|
-
```ruby
|
12
|
-
require 'dry-initializer'
|
13
|
-
|
14
|
-
class User
|
15
|
-
extend Dry::Initializer
|
16
|
-
|
17
|
-
param :name
|
18
|
-
option :email, optional: true
|
19
|
-
option :telefon, optional: true, as: :phone
|
20
|
-
end
|
21
|
-
|
22
|
-
user = User.new "Andy", telefon: "71002003040"
|
23
|
-
|
24
|
-
User.dry_initializer.attributes(user)
|
25
|
-
# => { name: "Andy", phone: "71002003040" }
|
26
|
-
```
|
27
|
-
|
28
|
-
What the method does is extracts *variables assigned* to the object (and skips unassigned ones like the `email` above). It doesn't matter whether you send it via `params` or `option`; we look at the result of the instantiation, not at the interface.
|
29
|
-
|
30
|
-
Method `public_attributes` works different. Let's look at the following example to see the difference:
|
31
|
-
|
32
|
-
```ruby
|
33
|
-
require 'dry-initializer'
|
34
|
-
|
35
|
-
class User
|
36
|
-
extend Dry::Initializer
|
37
|
-
|
38
|
-
param :name
|
39
|
-
option :telefon, optional: true, as: :phone
|
40
|
-
option :email, optional: true
|
41
|
-
option :token, optional: true, reader: :private
|
42
|
-
option :password, optional: true, reader: false
|
43
|
-
end
|
44
|
-
|
45
|
-
user = User.new "Andy", telefon: "71002003040", token: "foo", password: "bar"
|
46
|
-
|
47
|
-
User.dry_initializer.attributes(user)
|
48
|
-
# => { name: "Andy", phone: "71002003040", token: "foo", password: "bar" }
|
49
|
-
|
50
|
-
User.dry_initializer.public_attributes(user)
|
51
|
-
# => { name: "Andy", phone: "71002003040", email: nil }
|
52
|
-
```
|
53
|
-
|
54
|
-
Notice that `public_attribute` reads *public reader methods*, not variables. That's why it skips both the private `token`, and the `password` whose reader hasn't been defined.
|
55
|
-
|
56
|
-
Another difference concerns unassigned values. Because the reader `user.email` returns `nil` (its `@email` variable contains `Dry::Initializer::UNDEFINED` constant), the `public_attributes` adds this value to the hash using the method.
|
57
|
-
|
58
|
-
The third thing to mention is that you can override the reader, and it is the overriden method which will be used by `public_attributes`:
|
59
|
-
|
60
|
-
```ruby
|
61
|
-
require 'dry-initializer'
|
62
|
-
|
63
|
-
class User
|
64
|
-
extend Dry::Initializer
|
65
|
-
|
66
|
-
param :name
|
67
|
-
option :password, optional: true
|
68
|
-
|
69
|
-
def password
|
70
|
-
super.hash.to_s
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
user = User.new "Joe", password: "foo"
|
75
|
-
|
76
|
-
User.dry_initializer.attributes(user)
|
77
|
-
# => { user: "Joe", password: "foo" }
|
78
|
-
|
79
|
-
User.dry_initializer.public_attributes(user)
|
80
|
-
# => { user: "Joe", password: "-1844874613000160009" }
|
81
|
-
```
|
82
|
-
|
83
|
-
This feature works for the "extend Dry::Initializer" syntax. But what about "include Dry::Initializer.define ..."? Now we don't pollute class namespace with new methods, that's why `.dry_initializer` is absent.
|
84
|
-
|
85
|
-
To access config you can use a hack. Under the hood we define private instance method `#__dry_initializer_config__` which refers to the same container. So you can write:
|
86
|
-
|
87
|
-
```ruby
|
88
|
-
require 'dry-initializer'
|
89
|
-
|
90
|
-
class User
|
91
|
-
extend Dry::Initializer
|
92
|
-
param :name
|
93
|
-
end
|
94
|
-
|
95
|
-
user = User.new "Joe"
|
96
|
-
|
97
|
-
user.send(:__dry_initializer_config__).attributes(user)
|
98
|
-
# => { user: "Joe" }
|
99
|
-
|
100
|
-
user.send(:__dry_initializer_config__).public_attributes(user)
|
101
|
-
# => { user: "Joe" }
|
102
|
-
```
|
103
|
-
|
104
|
-
This is a hack because the `__dry_initializer_config__` is not a part of the gem's public interface; there's a possibility it can be changed or removed in the later releases.
|
105
|
-
|
106
|
-
We'll try to be careful with it, and mark it as deprecated method in case of such a removal.
|
@@ -1,39 +0,0 @@
|
|
1
|
-
---
|
2
|
-
title: Container Version
|
3
|
-
layout: gem-single
|
4
|
-
name: dry-initializer
|
5
|
-
---
|
6
|
-
|
7
|
-
Instead of extending a class with the `Dry::Initializer`, you can include a container with the `initializer` method only. This method should be preferred when you don't need subclassing.
|
8
|
-
|
9
|
-
```ruby
|
10
|
-
require 'dry-initializer'
|
11
|
-
|
12
|
-
class User
|
13
|
-
# notice `-> do .. end` syntax
|
14
|
-
include Dry::Initializer.define -> do
|
15
|
-
param :name, proc(&:to_s)
|
16
|
-
param :role, default: proc { 'customer' }
|
17
|
-
option :admin, default: proc { false }
|
18
|
-
end
|
19
|
-
end
|
20
|
-
```
|
21
|
-
|
22
|
-
If you still need the DSL (`param` and `option`) to be inherited, use the direct extension:
|
23
|
-
|
24
|
-
```ruby
|
25
|
-
require 'dry-initializer'
|
26
|
-
|
27
|
-
class BaseService
|
28
|
-
extend Dry::Initializer
|
29
|
-
alias_method :dependency, :param
|
30
|
-
end
|
31
|
-
|
32
|
-
class ShowUser < BaseService
|
33
|
-
dependency :user
|
34
|
-
|
35
|
-
def call
|
36
|
-
puts user&.name
|
37
|
-
end
|
38
|
-
end
|
39
|
-
```
|
@@ -1,43 +0,0 @@
|
|
1
|
-
---
|
2
|
-
title: Introduction & Usage
|
3
|
-
description: DSL for defining initializer params and options
|
4
|
-
layout: gem-single
|
5
|
-
order: 8
|
6
|
-
type: gem
|
7
|
-
name: dry-initializer
|
8
|
-
sections:
|
9
|
-
- container-version
|
10
|
-
- params-and-options
|
11
|
-
- options-tolerance
|
12
|
-
- optionals-and-defaults
|
13
|
-
- type-constraints
|
14
|
-
- readers
|
15
|
-
- inheritance
|
16
|
-
- skip-undefined
|
17
|
-
- attributes
|
18
|
-
- rails-support
|
19
|
-
---
|
20
|
-
|
21
|
-
`dry-initializer` is a simple mixin of class methods `params` and `options` for instances.
|
22
|
-
|
23
|
-
## Synopsis
|
24
|
-
|
25
|
-
```ruby
|
26
|
-
require 'dry-initializer'
|
27
|
-
|
28
|
-
class User
|
29
|
-
extend Dry::Initializer
|
30
|
-
|
31
|
-
param :name, proc(&:to_s)
|
32
|
-
param :role, default: proc { 'customer' }
|
33
|
-
option :admin, default: proc { false }
|
34
|
-
option :phone, optional: true
|
35
|
-
end
|
36
|
-
|
37
|
-
user = User.new 'Vladimir', 'admin', admin: true
|
38
|
-
|
39
|
-
user.name # => 'Vladimir'
|
40
|
-
user.role # => 'admin'
|
41
|
-
user.admin # => true
|
42
|
-
user.phone # => nil
|
43
|
-
```
|
@@ -1,43 +0,0 @@
|
|
1
|
-
---
|
2
|
-
title: Inheritance
|
3
|
-
layout: gem-single
|
4
|
-
name: dry-initializer
|
5
|
-
---
|
6
|
-
|
7
|
-
Subclassing preserves all definitions being made inside a superclass.
|
8
|
-
|
9
|
-
```ruby
|
10
|
-
require 'dry-initializer'
|
11
|
-
|
12
|
-
class User
|
13
|
-
extend Dry::Initializer
|
14
|
-
|
15
|
-
param :name
|
16
|
-
end
|
17
|
-
|
18
|
-
class Employee < User
|
19
|
-
param :position
|
20
|
-
end
|
21
|
-
|
22
|
-
employee = Employee.new('John', 'supercargo')
|
23
|
-
employee.name # => 'John'
|
24
|
-
employee.position # => 'supercargo'
|
25
|
-
|
26
|
-
employee = Employee.new # => fails because type
|
27
|
-
```
|
28
|
-
|
29
|
-
You can override params and options.
|
30
|
-
Such overriding leaves initial order of params (positional arguments) unchanged:
|
31
|
-
|
32
|
-
```ruby
|
33
|
-
class Employee < User
|
34
|
-
param :position, optional: true
|
35
|
-
param :name, default: proc { 'Unknown' }
|
36
|
-
end
|
37
|
-
|
38
|
-
user = User.new # => Boom! because User#name is required
|
39
|
-
employee = Employee.new # passes because who cares on employee's name
|
40
|
-
|
41
|
-
employee.name
|
42
|
-
# => 'Unknown' because it is the name that positioned first like in User
|
43
|
-
```
|
@@ -1,130 +0,0 @@
|
|
1
|
-
---
|
2
|
-
title: Optional Attributes and Default Values
|
3
|
-
layout: gem-single
|
4
|
-
name: dry-initializer
|
5
|
-
---
|
6
|
-
|
7
|
-
By default both params and options are mandatory. Use `:default` key to make them optional:
|
8
|
-
|
9
|
-
```ruby
|
10
|
-
require 'dry-initializer'
|
11
|
-
|
12
|
-
class User
|
13
|
-
extend Dry::Initializer
|
14
|
-
|
15
|
-
param :name, default: proc { 'Unknown user' }
|
16
|
-
option :email, default: proc { 'unknown@example.com' }
|
17
|
-
option :phone, optional: true
|
18
|
-
end
|
19
|
-
|
20
|
-
user = User.new
|
21
|
-
user.name # => 'Unknown user'
|
22
|
-
user.email # => 'unknown@example.com'
|
23
|
-
user.phone # => Dry::Initializer::UNDEFINED
|
24
|
-
|
25
|
-
user = User.new 'Vladimir', email: 'vladimir@example.com', phone: '71234567788'
|
26
|
-
user.name # => 'Vladimir'
|
27
|
-
user.email # => 'vladimir@example.com'
|
28
|
-
user.phone # => '71234567788'
|
29
|
-
```
|
30
|
-
|
31
|
-
You cannot define required **parameter** after optional one. The following example raises `SyntaxError` exception:
|
32
|
-
|
33
|
-
```ruby
|
34
|
-
require 'dry-initializer'
|
35
|
-
|
36
|
-
class User
|
37
|
-
extend Dry::Initializer
|
38
|
-
|
39
|
-
param :name, default: proc { 'Unknown name' }
|
40
|
-
param :email # => #<SyntaxError ...>
|
41
|
-
end
|
42
|
-
```
|
43
|
-
|
44
|
-
You should assign `nil` value explicitly. Otherwise an instance variable it will be left undefined. In both cases attribute reader method will return `nil`.
|
45
|
-
|
46
|
-
```ruby
|
47
|
-
require 'dry-initializer'
|
48
|
-
|
49
|
-
class User
|
50
|
-
extend Dry::Initializer
|
51
|
-
|
52
|
-
param :name
|
53
|
-
option :email, optional: true
|
54
|
-
end
|
55
|
-
|
56
|
-
user = User.new 'Andrew'
|
57
|
-
user.email # => nil
|
58
|
-
user.instance_variable_get :@email
|
59
|
-
# => Dry::Initializer::UNDEFINED
|
60
|
-
|
61
|
-
user = User.new 'Andrew', email: nil
|
62
|
-
user.email # => nil
|
63
|
-
user.instance_variable_get :@email
|
64
|
-
# => nil
|
65
|
-
```
|
66
|
-
|
67
|
-
You can also set `nil` as a default value:
|
68
|
-
|
69
|
-
```ruby
|
70
|
-
require 'dry-initializer'
|
71
|
-
|
72
|
-
class User
|
73
|
-
extend Dry::Initializer
|
74
|
-
|
75
|
-
param :name
|
76
|
-
option :email, default: proc { nil }
|
77
|
-
end
|
78
|
-
|
79
|
-
user = User.new 'Andrew'
|
80
|
-
user.email # => nil
|
81
|
-
user.instance_variable_get :@email
|
82
|
-
# => nil
|
83
|
-
```
|
84
|
-
|
85
|
-
You **must** wrap default values into procs.
|
86
|
-
|
87
|
-
If you need to **assign** proc as a default value, wrap it to another one:
|
88
|
-
|
89
|
-
```ruby
|
90
|
-
require 'dry-initializer'
|
91
|
-
|
92
|
-
class User
|
93
|
-
extend Dry::Initializer
|
94
|
-
|
95
|
-
param :name_proc, default: proc { proc { 'Unknown user' } }
|
96
|
-
end
|
97
|
-
|
98
|
-
user = User.new
|
99
|
-
user.name_proc.call # => 'Unknown user'
|
100
|
-
```
|
101
|
-
|
102
|
-
Proc will be executed in a scope of new instance. You can refer to other arguments:
|
103
|
-
|
104
|
-
```ruby
|
105
|
-
require 'dry-initializer'
|
106
|
-
|
107
|
-
class User
|
108
|
-
extend Dry::Initializer
|
109
|
-
|
110
|
-
param :name
|
111
|
-
param :email, default: proc { "#{name.downcase}@example.com" }
|
112
|
-
end
|
113
|
-
|
114
|
-
user = User.new 'Andrew'
|
115
|
-
user.email # => 'andrew@example.com'
|
116
|
-
```
|
117
|
-
|
118
|
-
**Warning**: when using lambdas instead of procs, don't forget an argument, required by [instance_eval][instance_eval] (you can skip in in a proc).
|
119
|
-
|
120
|
-
```ruby
|
121
|
-
require 'dry-initializer'
|
122
|
-
|
123
|
-
class User
|
124
|
-
extend Dry::Initializer
|
125
|
-
|
126
|
-
param :name, default: -> (obj) { 'Dude' }
|
127
|
-
end
|
128
|
-
```
|
129
|
-
|
130
|
-
[instance_eval]: http://ruby-doc.org/core-2.2.0/BasicObject.html#method-i-instance_eval
|