magic-support 0.3.2 → 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 +4 -4
- data/CHANGELOG.md +24 -0
- data/README.md +55 -13
- data/lib/magic/core_ext/kernel/then.rb +107 -0
- data/lib/magic/core_ext/kernel/utils.rb +1 -1
- data/lib/magic/loader.rb +1 -1
- data/lib/magic/support/version.rb +1 -1
- data/lib/rspec/method.rb +11 -5
- data/sig/magic/core_ext/kernel.rbs +7 -0
- metadata +57 -55
- data/.rspec +0 -3
- data/.rubocop.yml +0 -7
- data/lib/magic/core_ext/kernel/optional.rb +0 -31
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 300e982507adbfef7f0443c3a28e10eef71663ad657111414bcc378fbefa671e
|
|
4
|
+
data.tar.gz: 6d880303471f7fd11c0adb570bc243e3924cc84930fd06b449a7c85b6d820e77
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3ab3d1dbcf81b9d22a4ea50e24cf0ce11cf5d23231711d7baf8ee5cc556963d544a41152a6273fcea8980814100f0b3c9c5ea5ef68f1accd9add6daaa1cf002b
|
|
7
|
+
data.tar.gz: a83ab7bd0a8c1397e35dee965efcb155c2788a1fb13c11a4f2c58eac67167e39968c6544406cfc7242785b68cc0474b36acef9f559385e2005bb40ef570fb7b0
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,27 @@
|
|
|
1
|
+
## [0.4.0] — 2026-10-09
|
|
2
|
+
|
|
3
|
+
### Changed
|
|
4
|
+
|
|
5
|
+
- Moved to Ruby 3.4+.
|
|
6
|
+
|
|
7
|
+
#### `Kernel`
|
|
8
|
+
|
|
9
|
+
- Replaced `#optional` with `#then_try`.
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
#### `Kernel`
|
|
14
|
+
|
|
15
|
+
- Conditional `Kernel#then` via `if:`/`unless:` parameters.
|
|
16
|
+
When a condition isn’t met it returns self the same way `#then_try` does.
|
|
17
|
+
- Optional arguments for `Kernel#then_try`
|
|
18
|
+
to call `#try` under the hood.
|
|
19
|
+
Thus, one can replace, e.g., `.then_try { it.try :decorate }` with a shortcut: `.then_try :decorate`.
|
|
20
|
+
- `Kernel#then_try` without a block
|
|
21
|
+
to return an enumerator suppressing `NoMethodError`s.
|
|
22
|
+
Thus, one can call, e.g., `.then_try.detect &:odd?` for any `Numeric`, not just `Integer`.
|
|
23
|
+
|
|
24
|
+
|
|
1
25
|
## [0.3.2] — 2026-05-05
|
|
2
26
|
|
|
3
27
|
Works with Ruby 4+.
|
data/README.md
CHANGED
|
@@ -3,11 +3,15 @@
|
|
|
3
3
|

|
|
6
|
-
](
|
|
9
|
+
https://qlty.sh/gh/Alexander-Senko/projects/magic-support
|
|
8
10
|
)
|
|
9
|
-
](
|
|
14
|
+
https://qlty.sh/gh/Alexander-Senko/projects/magic-support
|
|
11
15
|
)
|
|
12
16
|
|
|
13
17
|
Magic Support is a collection of utility classes and standard library extensions
|
|
@@ -71,28 +75,66 @@ require 'magic/core_ext'
|
|
|
71
75
|
|
|
72
76
|
### Extensions to all objects
|
|
73
77
|
|
|
74
|
-
#### `#
|
|
78
|
+
#### `#then`
|
|
79
|
+
|
|
80
|
+
Yields self to the block and returns the block’s result, just like the original `then`, if the condition permits it.
|
|
81
|
+
Returns self otherwise, just like `then_try`.
|
|
82
|
+
|
|
83
|
+
```ruby
|
|
84
|
+
@people = Person
|
|
85
|
+
.then(if: new?) { it.where created_at: 1.hour.ago... }
|
|
86
|
+
.then(if: gdpr?, &:anonymize)
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Conditions may be callables, in which case they are called with self.
|
|
90
|
+
|
|
91
|
+
```ruby
|
|
92
|
+
data
|
|
93
|
+
.then(if: :compressed?) { decompress it }
|
|
94
|
+
.then(unless: :parsed?) { parse it }
|
|
95
|
+
.then(if: -> { it.size > LIMIT }) { shrink it }
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
With no condition keywords, it behaves like the standard `then`.
|
|
99
|
+
|
|
100
|
+
Defined in `core_ext/kernel/then`.
|
|
101
|
+
|
|
102
|
+
#### `#then_try`
|
|
75
103
|
|
|
76
104
|
Yields self to the block and returns the result of the block if it’s truthy, and self otherwise.
|
|
77
105
|
|
|
78
106
|
```ruby
|
|
79
107
|
rand(6) # returns 0–5
|
|
80
|
-
.
|
|
108
|
+
.then_try { it + 1 if one_based? } # returns 1–6 if 1-based, or
|
|
81
109
|
# the original 0–5 otherwise
|
|
82
110
|
```
|
|
83
111
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
Good usage for `#optional` is value piping in method chains with conditional processing:
|
|
112
|
+
Good usage for `#then_try` is value piping in method chains with conditional processing:
|
|
87
113
|
|
|
88
114
|
```ruby
|
|
89
115
|
@people = Person
|
|
90
|
-
.
|
|
91
|
-
.
|
|
92
|
-
.
|
|
116
|
+
.then_try { it.where created_at: (1.hour.ago...) if new? }
|
|
117
|
+
.then_try { anonymize it if gdpr? }
|
|
118
|
+
.then_try(:decorate)
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
When called without a block, the method returns an Enumerator, which can be used, for example, for `NoMethodError`-proof conditional circuit-breaking:
|
|
122
|
+
|
|
123
|
+
```ruby
|
|
124
|
+
101.then_try.detect &:odd? # => 101
|
|
125
|
+
102.then_try.detect &:odd? # => nil
|
|
126
|
+
1.3.then_try.detect &:odd? # => nil
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Traditional `#then` behaves like this:
|
|
130
|
+
|
|
131
|
+
```ruby
|
|
132
|
+
101.then.detect &:odd? # => 101
|
|
133
|
+
102.then.detect &:odd? # => nil
|
|
134
|
+
1.3.then.detect &:odd? # raises NoMethodError
|
|
93
135
|
```
|
|
94
136
|
|
|
95
|
-
Defined in `core_ext/kernel/
|
|
137
|
+
Defined in `core_ext/kernel/then`.
|
|
96
138
|
|
|
97
139
|
## Gems
|
|
98
140
|
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'utils'
|
|
4
|
+
|
|
5
|
+
require 'active_support/core_ext/object/try'
|
|
6
|
+
|
|
7
|
+
Magic::CoreExt.kernel do
|
|
8
|
+
# Yields self to the block and returns the block’s result, just like
|
|
9
|
+
# the original +then+, if the condition permits it.
|
|
10
|
+
# Returns self otherwise, just like +then_try+.
|
|
11
|
+
#
|
|
12
|
+
# rand(6) # returns 0–5
|
|
13
|
+
# .then(&:succ, if: one_based?) # returns 1–6 if 1-based, or
|
|
14
|
+
# # the original 0–5 otherwise
|
|
15
|
+
#
|
|
16
|
+
# @people = Person
|
|
17
|
+
# .then(if: new?) { it.where created_at: 1.hour.ago... }
|
|
18
|
+
# .then(if: gdpr?, &:anonymize)
|
|
19
|
+
#
|
|
20
|
+
# Conditions may be callables, in which case they are called with self.
|
|
21
|
+
#
|
|
22
|
+
# data
|
|
23
|
+
# .then(if: :compressed?) { decompress it }
|
|
24
|
+
# .then(unless: :parsed?) { parse it }
|
|
25
|
+
# .then(if: -> { it.size > LIMIT }) { shrink it }
|
|
26
|
+
#
|
|
27
|
+
# With no condition keywords, it behaves like the standard +then+.
|
|
28
|
+
def then **conditions, &block # rubocop:disable Metrics
|
|
29
|
+
return super unless conditions.any?
|
|
30
|
+
|
|
31
|
+
return Enumerator.new do |yielder|
|
|
32
|
+
self.then **conditions do
|
|
33
|
+
yielder << it
|
|
34
|
+
end
|
|
35
|
+
end unless block
|
|
36
|
+
|
|
37
|
+
if (keywords = conditions.keys - %i[ if unless ]).any?
|
|
38
|
+
require 'active_support/core_ext/enumerable'
|
|
39
|
+
|
|
40
|
+
raise ArgumentError, "unknown keyword#{'s' if keywords.many?}: #{keywords.map(&:inspect) * ', '}"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
conditions.transform_values! do |condition|
|
|
44
|
+
if condition.respond_to? :to_proc
|
|
45
|
+
condition.to_proc[self]
|
|
46
|
+
else
|
|
47
|
+
condition
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
if conditions.fetch(:if, true) and not conditions.fetch(:unless, false)
|
|
52
|
+
super &block
|
|
53
|
+
else
|
|
54
|
+
self
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Yields self to the block and returns the result of the block if it’s
|
|
59
|
+
# truthy, and self otherwise.
|
|
60
|
+
#
|
|
61
|
+
# rand(6) # returns 0–5
|
|
62
|
+
# .then_try { it + 1 if one_based? } # returns 1–6 if 1-based, or
|
|
63
|
+
# # the original 0–5 otherwise
|
|
64
|
+
#
|
|
65
|
+
# It can be considered as a conditional +then+.
|
|
66
|
+
#
|
|
67
|
+
# Good usage for +then_try+ is value piping in method chains with
|
|
68
|
+
# conditional processing:
|
|
69
|
+
#
|
|
70
|
+
# @people = Person
|
|
71
|
+
# .then_try { it.where created_at: (1.hour.ago...) if new? }
|
|
72
|
+
# .then_try { anonymize it if gdpr? }
|
|
73
|
+
# .then_try(:decorate)
|
|
74
|
+
#
|
|
75
|
+
# See the proposal: https://bugs.ruby-lang.org/issues/21435
|
|
76
|
+
#
|
|
77
|
+
# When called without a block, the method returns an Enumerator, which
|
|
78
|
+
# can be used, for example, for +NoMethodError+-proof conditional
|
|
79
|
+
# circuit-breaking:
|
|
80
|
+
#
|
|
81
|
+
# 101.then.detect &:odd? # => 101
|
|
82
|
+
# 102.then.detect &:odd? # => nil
|
|
83
|
+
# 1.3.then.detect &:odd? # raises NoMethodError
|
|
84
|
+
#
|
|
85
|
+
# 101.then_try.detect &:odd? # => 101
|
|
86
|
+
# 102.then_try.detect &:odd? # => nil
|
|
87
|
+
# 1.3.then_try.detect &:odd? # => nil
|
|
88
|
+
def then_try(*args, **, &)
|
|
89
|
+
tap do
|
|
90
|
+
result = if args.any?
|
|
91
|
+
try(*args, **, &)
|
|
92
|
+
else
|
|
93
|
+
# Enumerator mode
|
|
94
|
+
return Enumerator.new do |yielder|
|
|
95
|
+
yielder << self
|
|
96
|
+
rescue NoMethodError => error
|
|
97
|
+
raise unless
|
|
98
|
+
self == error.receiver
|
|
99
|
+
end unless block_given?
|
|
100
|
+
|
|
101
|
+
yield self
|
|
102
|
+
end or next # bypass
|
|
103
|
+
|
|
104
|
+
break result # `#then` mode
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
data/lib/magic/loader.rb
CHANGED
data/lib/rspec/method.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'active_support/concern'
|
|
4
|
-
require 'magic/core_ext/kernel/
|
|
4
|
+
require 'magic/core_ext/kernel/then'
|
|
5
5
|
|
|
6
6
|
module RSpec # :nodoc:
|
|
7
7
|
module Method
|
|
@@ -11,7 +11,7 @@ module RSpec # :nodoc:
|
|
|
11
11
|
}
|
|
12
12
|
.map { |name, pattern| "(?<#{name}>#{pattern})" }
|
|
13
13
|
.join
|
|
14
|
-
.then { /(?:^|\s)#{
|
|
14
|
+
.then { /(?:^|\s)#{it}(?:$|\s)?/ } # may be surrounded by some text
|
|
15
15
|
|
|
16
16
|
# @api public
|
|
17
17
|
# Container module for method specs.
|
|
@@ -43,6 +43,7 @@ module RSpec # :nodoc:
|
|
|
43
43
|
description.match(REFERENCE) in { scope:, name: } or
|
|
44
44
|
raise ArgumentError, "'#{description}' doesn't look like a method reference"
|
|
45
45
|
|
|
46
|
+
adjust_description if description.start_with? scope
|
|
46
47
|
backup_subject
|
|
47
48
|
|
|
48
49
|
let :receiver do
|
|
@@ -62,7 +63,7 @@ module RSpec # :nodoc:
|
|
|
62
63
|
def backup_subject
|
|
63
64
|
subject_method = instance_method :subject
|
|
64
65
|
|
|
65
|
-
while subject_method.owner.then { not
|
|
66
|
+
while subject_method.owner.then { not it.respond_to? :metadata or it.metadata[:method] }
|
|
66
67
|
subject_method = subject_method.super_method or break
|
|
67
68
|
end
|
|
68
69
|
|
|
@@ -72,6 +73,11 @@ module RSpec # :nodoc:
|
|
|
72
73
|
let(:__subject__) { method(:subject).super_method[] }
|
|
73
74
|
end
|
|
74
75
|
end
|
|
76
|
+
|
|
77
|
+
def adjust_description
|
|
78
|
+
metadata[:full_description]
|
|
79
|
+
.sub!(/#{described_class}\s+#{description}/, "#{described_class}#{description}")
|
|
80
|
+
end
|
|
75
81
|
end
|
|
76
82
|
|
|
77
83
|
def subject
|
|
@@ -95,7 +101,7 @@ module RSpec # :nodoc:
|
|
|
95
101
|
shared_context :delegated do |to:, with: nil|
|
|
96
102
|
before do
|
|
97
103
|
allow(to).to receive(method_name)
|
|
98
|
-
.
|
|
104
|
+
.then(if: with) { it.with *with }
|
|
99
105
|
.and_call_original
|
|
100
106
|
end
|
|
101
107
|
|
|
@@ -115,6 +121,6 @@ module RSpec # :nodoc:
|
|
|
115
121
|
end
|
|
116
122
|
|
|
117
123
|
configure do
|
|
118
|
-
|
|
124
|
+
it.backtrace_exclusion_patterns << %r'/lib/rspec/method'
|
|
119
125
|
end
|
|
120
126
|
end
|
|
@@ -2,6 +2,13 @@ module Magic
|
|
|
2
2
|
module CoreExt
|
|
3
3
|
module Kernel
|
|
4
4
|
MODULES: Array[Module]
|
|
5
|
+
|
|
6
|
+
def then_try: [U] { (self) -> U } -> (U | self)
|
|
7
|
+
| (interned method_name, *untyped, **untyped) ?{ (*untyped, **untyped) -> untyped } -> (untyped | self)
|
|
8
|
+
| -> Enumerator[self, untyped]
|
|
9
|
+
|
|
10
|
+
def then: [U] (?if: bool, ?unless: bool) { (self) -> U } -> (U | self)
|
|
11
|
+
| (?if: bool, ?unless: bool) -> Enumerator[self, untyped]
|
|
5
12
|
end
|
|
6
13
|
end
|
|
7
14
|
end
|
metadata
CHANGED
|
@@ -1,82 +1,84 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: magic-support
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
|
-
- Alexander Senko
|
|
7
|
+
- Alexander Senko
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
|
-
- !ruby/object:Gem::Dependency
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: activesupport
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
-
|
|
17
|
+
- ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: "0"
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
-
|
|
25
|
+
- ">="
|
|
26
|
+
- !ruby/object:Gem::Version
|
|
27
|
+
version: "0"
|
|
26
28
|
description: Utility classes and Ruby extensions beyond Active Support.
|
|
27
29
|
email:
|
|
28
|
-
- Alexander.Senko@gmail.com
|
|
30
|
+
- Alexander.Senko@gmail.com
|
|
29
31
|
executables: []
|
|
30
32
|
extensions: []
|
|
31
33
|
extra_rdoc_files: []
|
|
32
34
|
files:
|
|
33
|
-
-
|
|
34
|
-
-
|
|
35
|
-
-
|
|
36
|
-
-
|
|
37
|
-
-
|
|
38
|
-
-
|
|
39
|
-
-
|
|
40
|
-
- lib/magic/core_ext.rb
|
|
41
|
-
- lib/magic/core_ext/kernel.rb
|
|
42
|
-
- lib/magic/
|
|
43
|
-
- lib/magic/
|
|
44
|
-
- lib/magic/
|
|
45
|
-
- lib/magic/support.rb
|
|
46
|
-
- lib/
|
|
47
|
-
- lib/
|
|
48
|
-
- lib/
|
|
49
|
-
- lib/
|
|
50
|
-
-
|
|
51
|
-
- sig/
|
|
52
|
-
- sig/magic/
|
|
53
|
-
- sig/magic/
|
|
54
|
-
- sig/
|
|
55
|
-
- sig/
|
|
56
|
-
- sig/
|
|
57
|
-
|
|
58
|
-
- sig/rubygems/author.rbs
|
|
59
|
-
homepage: https://github.com/Alexander-Senko/magic-support
|
|
35
|
+
- CHANGELOG.md
|
|
36
|
+
- CODE_OF_CONDUCT.md
|
|
37
|
+
- LICENSE.txt
|
|
38
|
+
- README.md
|
|
39
|
+
- Rakefile
|
|
40
|
+
- lib/magic/core_ext.rb
|
|
41
|
+
- lib/magic/core_ext/kernel.rb
|
|
42
|
+
- lib/magic/core_ext/kernel/then.rb
|
|
43
|
+
- lib/magic/core_ext/kernel/utils.rb
|
|
44
|
+
- lib/magic/loader.rb
|
|
45
|
+
- lib/magic/support.rb
|
|
46
|
+
- lib/magic/support/authors.rb
|
|
47
|
+
- lib/magic/support/version.rb
|
|
48
|
+
- lib/rspec/method.rb
|
|
49
|
+
- lib/rspec/method/its.rb
|
|
50
|
+
- lib/rubygems/author.rb
|
|
51
|
+
- sig/lib/magic/support/author.rbs
|
|
52
|
+
- sig/magic/core_ext.rbs
|
|
53
|
+
- sig/magic/core_ext/kernel.rbs
|
|
54
|
+
- sig/magic/loader.rbs
|
|
55
|
+
- sig/magic/support.rbs
|
|
56
|
+
- sig/rspec/method.rbs
|
|
57
|
+
- sig/rspec/method/its.rbs
|
|
58
|
+
- sig/rubygems/author.rbs
|
|
59
|
+
homepage: "https://github.com/Alexander-Senko/magic-support"
|
|
60
60
|
licenses:
|
|
61
|
-
- MIT
|
|
61
|
+
- MIT
|
|
62
62
|
metadata:
|
|
63
|
-
source_code_uri: https://github.com/Alexander-Senko/magic-support
|
|
64
|
-
changelog_uri: https://github.com/Alexander-Senko/magic-support/blob/v0.
|
|
63
|
+
source_code_uri: "https://github.com/Alexander-Senko/magic-support"
|
|
64
|
+
changelog_uri: "https://github.com/Alexander-Senko/magic-support/blob/v0.4.0/CHANGELOG.md"
|
|
65
65
|
rdoc_options: []
|
|
66
66
|
require_paths:
|
|
67
|
-
- lib
|
|
67
|
+
- lib
|
|
68
68
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
69
69
|
requirements:
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
-
|
|
71
|
+
- ">="
|
|
72
|
+
- !ruby/object:Gem::Version
|
|
73
|
+
version: "3.4"
|
|
73
74
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
74
75
|
requirements:
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
76
|
+
-
|
|
77
|
+
- ">="
|
|
78
|
+
- !ruby/object:Gem::Version
|
|
79
|
+
version: "0"
|
|
78
80
|
requirements: []
|
|
79
|
-
rubygems_version:
|
|
81
|
+
rubygems_version: 4.1.0.dev
|
|
80
82
|
specification_version: 4
|
|
81
83
|
summary: Active Support extended
|
|
82
84
|
test_files: []
|
data/.rspec
DELETED
data/.rubocop.yml
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative 'utils'
|
|
4
|
-
|
|
5
|
-
Magic::CoreExt.kernel do
|
|
6
|
-
# Yields self to the block and returns the result of the block if it’s
|
|
7
|
-
# truthy, and self otherwise.
|
|
8
|
-
#
|
|
9
|
-
# rand(6) # returns 0–5
|
|
10
|
-
# .optional { it + 1 if one_based? } # returns 1–6 if 1-based, or
|
|
11
|
-
# # the original 0–5 otherwise
|
|
12
|
-
#
|
|
13
|
-
# It can be considered as a conditional +then+.
|
|
14
|
-
#
|
|
15
|
-
# Good usage for +optional+ is value piping in method chains with
|
|
16
|
-
# conditional processing:
|
|
17
|
-
#
|
|
18
|
-
# @people = Person
|
|
19
|
-
# .optional { it.where created_at: (1.hour.ago...) if new? }
|
|
20
|
-
# .optional { anonymize it if gdpr? }
|
|
21
|
-
# .optional { try :decorate }
|
|
22
|
-
#
|
|
23
|
-
def optional
|
|
24
|
-
tap do
|
|
25
|
-
result = yield(self) or
|
|
26
|
-
next
|
|
27
|
-
|
|
28
|
-
break result
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|