inline_transforms 0.1.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 +7 -0
- data/.ruby-version +1 -0
- data/.yardopts +4 -0
- data/LICENSE +21 -0
- data/README.md +159 -0
- data/Rakefile +10 -0
- data/lib/inline_transforms/version.rb +3 -0
- data/lib/inline_transforms.rb +78 -0
- metadata +50 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 22f30721666a47350279cb918ceadc3887f4fa5aaca5202901559ec690778fa6
|
|
4
|
+
data.tar.gz: bc800383746ebb80919e00a9103fac32ad4cf8c8863a5207c2ffcd186de58ca4
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 423e20167b171a3a929c9dcc063d9bcb7a10cc91a1f0b6cab20817df8ababf10471f96196c09994dad0e7b0999ac324d1466d19d99f680a7ebdb5b5a57e77ea8
|
|
7
|
+
data.tar.gz: 65bb28caa0f2d10c3a45a5a45a05574f55f230c77f47783bd5ec819280d62809c1cd2808d314176f62588e02f107d42ccb17caac0121ed16f9d205d59bd9bae1
|
data/.ruby-version
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.4
|
data/.yardopts
ADDED
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Nestor Custodio
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
[](https://rubygems.org/gems/inline_transforms)
|
|
2
|
+
[](https://tldrlegal.com/license/mit-license)
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
# Inline Transforms
|
|
6
|
+
|
|
7
|
+
Ruby is an incredibly expressive (and easy to read!) language, but lacks a way for you to transform a value _inline_ without resorting to nested ternaries (🫠). This gem allows you to do exactly that in a way that still feels like _Ruby_ (i.e. via _value manipulation_ through method calls rather than classic flow control blocks).
|
|
8
|
+
|
|
9
|
+
In simplest terms:
|
|
10
|
+
```ruby
|
|
11
|
+
# "Unless" Logic:
|
|
12
|
+
|
|
13
|
+
final_value = original_value
|
|
14
|
+
final_value = different_value if original_value == a_bad_thing
|
|
15
|
+
|
|
16
|
+
# ... or ...
|
|
17
|
+
|
|
18
|
+
final_value = if original_value == a_bad_thing
|
|
19
|
+
different_value
|
|
20
|
+
else
|
|
21
|
+
original_value
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# ... becomes ...
|
|
25
|
+
|
|
26
|
+
final_value = original_value.unless a_bad_thing,
|
|
27
|
+
then: different_value
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
# "Transform" Logic:
|
|
31
|
+
|
|
32
|
+
final_value = case original_value
|
|
33
|
+
when true then 'success'
|
|
34
|
+
when false then 'failure'
|
|
35
|
+
when String then %(error: "#{original_value}")
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# ... becomes ...
|
|
39
|
+
|
|
40
|
+
final_value = original_value.transform true => 'success',
|
|
41
|
+
false => 'failure',
|
|
42
|
+
String => %(error: "#{original_value}")
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
[Full documentation is available here](https://nestor-custodio.github.io/inline_transforms), but do read below for a crash course on availble featues!
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
## Installation
|
|
50
|
+
|
|
51
|
+
- If your project uses [Bundler](https://github.com/bundler/bundler):
|
|
52
|
+
- Add one of the following to your application's Gemfile:
|
|
53
|
+
```ruby
|
|
54
|
+
# For on-demand usage:
|
|
55
|
+
|
|
56
|
+
gem 'inline_transforms'
|
|
57
|
+
```
|
|
58
|
+
- And then run a:
|
|
59
|
+
```shell
|
|
60
|
+
$ bundle install
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
- Or, you can keep things simple with a manual install:
|
|
64
|
+
```shell
|
|
65
|
+
$ gem install inline_transforms
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
## Usage
|
|
70
|
+
|
|
71
|
+
### Object#unless
|
|
72
|
+
|
|
73
|
+
`unless` lets you specify a "bad" value and a `then` replacement.
|
|
74
|
+
|
|
75
|
+
- If your `then` replacement is a `Proc`, it is resolved (via `call`) before being returned.
|
|
76
|
+
- This method uses **case comparison** (`===`), so you can check for range inclusion or class.
|
|
77
|
+
|
|
78
|
+
```ruby
|
|
79
|
+
final = value.unless bad_value, then: fallback_value
|
|
80
|
+
# ... or ...
|
|
81
|
+
final = value.unless bad_value, then: -> { some_method_call with_params }
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
### Object#transform
|
|
86
|
+
|
|
87
|
+
`transform` lets you specify a transformation hash and will return the value for the first matching key, or (if no matching key is found) the `:else` value.
|
|
88
|
+
|
|
89
|
+
- Any `Proc` values in the transform hash are resolved (via `call`) before being returned.
|
|
90
|
+
- This method uses **case comparison** (`===`), so range and class keys work as you expect.
|
|
91
|
+
|
|
92
|
+
```ruby
|
|
93
|
+
final = value.transform key_1 => value_1,
|
|
94
|
+
key_2 => value_2,
|
|
95
|
+
# ...
|
|
96
|
+
else: else_value
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
## Potential Gotchas
|
|
101
|
+
|
|
102
|
+
- `Proc` instances are only resolved if they _need to be returned and are not the original value_:
|
|
103
|
+
```ruby
|
|
104
|
+
value = -> { 'value proc' }
|
|
105
|
+
replacement_proc = -> { 'replacement proc' }
|
|
106
|
+
|
|
107
|
+
# Returns the original `value`, still a *Proc*.
|
|
108
|
+
#
|
|
109
|
+
# The original `value` is never resolved.
|
|
110
|
+
# The `replacement_proc` is not resolved.
|
|
111
|
+
#
|
|
112
|
+
final = value.unless 99, then: replacement_proc
|
|
113
|
+
|
|
114
|
+
# Returns the *String* 'replacement proc'.
|
|
115
|
+
#
|
|
116
|
+
# The original `value` is never resolved.
|
|
117
|
+
# The `replacement_proc` DOES get resolved.
|
|
118
|
+
#
|
|
119
|
+
final = value.unless value, then: replacement_proc
|
|
120
|
+
|
|
121
|
+
# Returns 99.
|
|
122
|
+
#
|
|
123
|
+
# The original `value` is never resolved.
|
|
124
|
+
# The `replacement_proc` is not resolved.
|
|
125
|
+
#
|
|
126
|
+
final = value.transform value => 99, else: replacement_proc
|
|
127
|
+
|
|
128
|
+
# Returns the *String* 'replacement proc'.
|
|
129
|
+
#
|
|
130
|
+
# The original `value` is never resolved.
|
|
131
|
+
# The `replacement_proc` DOES get resolved.
|
|
132
|
+
#
|
|
133
|
+
final = value.transform 99 => 99, else: replacement_proc
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
- Because _return_ `Proc`s are resolved before being passed back, you have to "proc-wrap" any `Proc` you want returned as-is (😵💫):
|
|
137
|
+
```ruby
|
|
138
|
+
value = 'some value'
|
|
139
|
+
replacement_proc = -> { 'replacement proc' }
|
|
140
|
+
|
|
141
|
+
# Returns the `replacement_proc`, still a *Proc*.
|
|
142
|
+
#
|
|
143
|
+
value.unless 99, then: -> { replacement_proc }
|
|
144
|
+
```
|
|
145
|
+
It should be _exceedingly rare_ for someone to want to do this, but it _is_ supported and this is how you would make that happen.
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
## Contribution / Development
|
|
149
|
+
|
|
150
|
+
Bug reports and pull requests are welcome at: [https://github.com/nestor-custodio/inline_transforms](https://github.com/nestor-custodio/inline_transforms)
|
|
151
|
+
|
|
152
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
153
|
+
|
|
154
|
+
Linting is courtesy of [Rubocop](https://docs.rubocop.org/) (`rake rubocop`) and documentation is built using [YARD](https://yardoc.org/). Please ensure you have a clean bill of health from Rubocop and that any new features and/or changes to behaviour are reflected in the adjacent documentation before submitting a pull request.
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
## License
|
|
158
|
+
|
|
159
|
+
The `inline_transforms` gem is available as open source under the terms of the [MIT License](https://tldrlegal.com/license/mit-license).
|
data/Rakefile
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
require_relative 'inline_transforms/version'
|
|
2
|
+
|
|
3
|
+
# Defines `unless` and `transform`, which we'll then want to make available in `Object` instances.
|
|
4
|
+
#
|
|
5
|
+
module InlineTransforms
|
|
6
|
+
# Our use of case equality in matching bad/target values
|
|
7
|
+
# is intentional and part of the promise behind the gem.
|
|
8
|
+
#
|
|
9
|
+
# rubocop:disable Style/CaseEquality
|
|
10
|
+
|
|
11
|
+
# Returns `self` ... unless it matches a "bad" value, in which case it returns an alternate (`then:`) value.
|
|
12
|
+
#
|
|
13
|
+
# (NOTE: this takes a `then: nil` named param, but is defined as taking `(**options)` because `then` is reserved.)
|
|
14
|
+
#
|
|
15
|
+
#
|
|
16
|
+
# @param bad_value [Object]
|
|
17
|
+
# The one value we consider "bad", and for which we'd like the `then:` option back instead.
|
|
18
|
+
#
|
|
19
|
+
# @option then: [Object]
|
|
20
|
+
# The value we'd like back if `self` matches the `bad_value` **using case comparison**.
|
|
21
|
+
# Defaults to `nil`.
|
|
22
|
+
#
|
|
23
|
+
# @return
|
|
24
|
+
# Returns either `self` or the value given as the `then:` option.
|
|
25
|
+
#
|
|
26
|
+
def unless(bad_value, **options)
|
|
27
|
+
return self unless inline_transforms_equality? bad_value
|
|
28
|
+
|
|
29
|
+
alt_value = options[:then]
|
|
30
|
+
return alt_value.call if alt_value.is_a? Proc
|
|
31
|
+
|
|
32
|
+
alt_value
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Returns `self` ... unless it matches one of the keys in the given "transformation hash", in which case the
|
|
36
|
+
# corresponding hash value is returned. If no matching hash key is found, this returns a fallback (`else:`) value.
|
|
37
|
+
#
|
|
38
|
+
# (NOTE: this takes an `else: nil` named param, but is defined as taking `(**options)` because `else` is reserved.)
|
|
39
|
+
#
|
|
40
|
+
#
|
|
41
|
+
# @option **
|
|
42
|
+
# A hash of keys to case-compare against `self` so we can return the corresponding value.
|
|
43
|
+
#
|
|
44
|
+
# @option else: [Object]
|
|
45
|
+
# The fallback value to return if no matching key is found.
|
|
46
|
+
#
|
|
47
|
+
# @return
|
|
48
|
+
# Returns either `self`, one of the transformation hash values, or the `else:` option.
|
|
49
|
+
#
|
|
50
|
+
def transform(**options)
|
|
51
|
+
default = options.delete :else
|
|
52
|
+
|
|
53
|
+
options.each { |key, value| return value.unless Proc, then: -> { value.call } if inline_transforms_equality? key }
|
|
54
|
+
default
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
private
|
|
58
|
+
|
|
59
|
+
# You can't case-compare *against* a `Proc` because `Proc#===` is an alias for `Proc#call`. (?!)
|
|
60
|
+
# So we have to be careful when testing for this.
|
|
61
|
+
#
|
|
62
|
+
# @param value [Object]
|
|
63
|
+
# The value against which to case-compare `self`.
|
|
64
|
+
#
|
|
65
|
+
# @return [true, false]
|
|
66
|
+
#
|
|
67
|
+
def inline_transforms_equality?(value)
|
|
68
|
+
return value == self if value.is_a? Proc
|
|
69
|
+
|
|
70
|
+
value === self
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# rubocop:enable Style/CaseEquality
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Gets the `InlineTransforms` methods.
|
|
77
|
+
#
|
|
78
|
+
class Object; include InlineTransforms; end # rubocop:disable Style/OneClassPerFile
|
metadata
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: inline_transforms
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Nestor Custodio
|
|
8
|
+
bindir: exe
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies: []
|
|
12
|
+
email:
|
|
13
|
+
- nestor@custodio.org
|
|
14
|
+
executables: []
|
|
15
|
+
extensions: []
|
|
16
|
+
extra_rdoc_files: []
|
|
17
|
+
files:
|
|
18
|
+
- ".ruby-version"
|
|
19
|
+
- ".yardopts"
|
|
20
|
+
- LICENSE
|
|
21
|
+
- README.md
|
|
22
|
+
- Rakefile
|
|
23
|
+
- lib/inline_transforms.rb
|
|
24
|
+
- lib/inline_transforms/version.rb
|
|
25
|
+
homepage: https://github.com/nestor-custodio/inline_transforms
|
|
26
|
+
licenses:
|
|
27
|
+
- MIT
|
|
28
|
+
metadata:
|
|
29
|
+
allowed_push_host: https://rubygems.org
|
|
30
|
+
homepage_uri: https://github.com/nestor-custodio/inline_transforms
|
|
31
|
+
changelog_uri: https://github.com/nestor-custodio/inline_transforms/CHANGELOG.md
|
|
32
|
+
rubygems_mfa_required: 'true'
|
|
33
|
+
rdoc_options: []
|
|
34
|
+
require_paths:
|
|
35
|
+
- lib
|
|
36
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '3.4'
|
|
41
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
42
|
+
requirements:
|
|
43
|
+
- - ">="
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
version: '0'
|
|
46
|
+
requirements: []
|
|
47
|
+
rubygems_version: 3.6.9
|
|
48
|
+
specification_version: 4
|
|
49
|
+
summary: Facilitates inline value logic.
|
|
50
|
+
test_files: []
|