attribool 0.0.2 → 1.0.1
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/.github/workflows/ruby.yml +19 -8
- data/Gemfile.lock +2 -2
- data/README.md +76 -20
- data/attribool.gemspec +1 -1
- data/lib/attribool/attribute.rb +62 -0
- data/lib/attribool/version.rb +25 -3
- data/lib/attribool.rb +48 -52
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e18815dc8107a42c84084e2c35614d8111f7ae827224b4b78cbb3e920ff9c970
|
4
|
+
data.tar.gz: 84642d3baca03e19bf84794ed88f2696d1f639801b79f55cd9fc2636309f8061
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3984a29d0285e92995b01d36ba9fbe0fe4919b9800116bff642ff5e7f0ee8e3fe1c4444a5bb1f3494f87e41228c31b4f0a7eec086ae3f3e5f07f255a5943ba41
|
7
|
+
data.tar.gz: 68246fd9004eb745078a8399ee4dc160ba2b06535a12fad81173958053c738c523fe5df152e266e2103e74f84715f9ca0bb309726eb30159e313f45efd9a8761
|
data/.github/workflows/ruby.yml
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
# This workflow uses actions that are not certified by GitHub.
|
2
|
+
# They are provided by a third-party and are governed by
|
3
|
+
# separate terms of service, privacy policy, and support
|
4
|
+
# documentation.
|
5
|
+
# This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
|
6
|
+
# For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
|
7
|
+
|
1
8
|
name: Ruby
|
2
9
|
|
3
10
|
on:
|
@@ -10,15 +17,19 @@ jobs:
|
|
10
17
|
test:
|
11
18
|
|
12
19
|
runs-on: ubuntu-latest
|
20
|
+
strategy:
|
21
|
+
matrix:
|
22
|
+
ruby-version: ['2.6', '2.7', '3.0']
|
13
23
|
|
14
24
|
steps:
|
15
25
|
- uses: actions/checkout@v2
|
16
|
-
- name: Set up Ruby
|
17
|
-
|
26
|
+
- name: Set up Ruby
|
27
|
+
# To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
|
28
|
+
# change this to (see https://github.com/ruby/setup-ruby#versioning):
|
29
|
+
# uses: ruby/setup-ruby@v1
|
30
|
+
uses: ruby/setup-ruby@473e4d8fe5dd94ee328fdfca9f8c9c7afc9dae5e
|
18
31
|
with:
|
19
|
-
ruby-version:
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
bundle install
|
24
|
-
bundle exec rake test
|
32
|
+
ruby-version: ${{ matrix.ruby-version }}
|
33
|
+
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
34
|
+
- name: Run tests
|
35
|
+
run: bundle exec rake
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -3,22 +3,26 @@
|
|
3
3
|
[](https://badge.fury.io/rb/attribool)
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
5
5
|
|
6
|
-
> Pre-release version. Everything works, but not everything is documented.
|
7
|
-
|
8
6
|
Ruby macros for creating boolean methods for attributes that may or may not be
|
9
|
-
booleans themselves. This is done via coercion based on truthiness
|
10
|
-
|
11
|
-
|
12
|
-
|
7
|
+
booleans themselves. This is done via either coercion based on truthiness, or a
|
8
|
+
user-defined condition.
|
9
|
+
|
10
|
+
For example, if you have an attribute of `@name`, and you want to know if
|
11
|
+
`@name` is not `nil`, you can declare `bool_reader :name`, which will define the
|
12
|
+
method `name?`. This method will return true if `@name` is truthy.
|
13
13
|
|
14
14
|
The `bool_reader` also comes with some handy options. For example, you can
|
15
|
-
[define a method name](#a-bool_reader-with-method-name
|
16
|
-
more sense.
|
15
|
+
[define a method name](#a-bool_reader-with-method-name) that makes
|
16
|
+
more sense. Using the same example as above, if your attribute is `@name`, but
|
17
17
|
you'd like for your boolean method to be called `named?`, you can use
|
18
|
-
`bool_reader :name,
|
18
|
+
`bool_reader :name, method_name: :named?`.
|
19
19
|
[Conditionals](#a-bool_reader-with-method-name-and-conditional) can also be set
|
20
20
|
with lambdas via the `condition:` keyword argument.
|
21
21
|
|
22
|
+
The first argument is always the instance variable to check for truthiness.
|
23
|
+
Because of this, it is also valid syntax to use `bool_reader :@name`, if it
|
24
|
+
makes more sense to you.
|
25
|
+
|
22
26
|
Macros also exist for `bool_writer` and `bool_accessor`. When a writer
|
23
27
|
method is defined, the value will always be coerced into a boolean before
|
24
28
|
setting the attribute.
|
@@ -49,10 +53,14 @@ bundle exec rake install
|
|
49
53
|
require 'attribool'
|
50
54
|
|
51
55
|
class Person
|
52
|
-
|
56
|
+
extend Attribool
|
53
57
|
|
54
58
|
attr_accessor :name
|
55
59
|
bool_reader :name
|
60
|
+
# OR
|
61
|
+
# bool_reader :@name
|
62
|
+
# bool_reader 'name'
|
63
|
+
# bool_reader '@name'
|
56
64
|
end
|
57
65
|
|
58
66
|
person = Person.new
|
@@ -66,26 +74,23 @@ person.name?
|
|
66
74
|
# true, because @name is truthy.
|
67
75
|
```
|
68
76
|
|
69
|
-
#### A bool_reader with method name
|
77
|
+
#### A bool_reader with method name
|
70
78
|
```ruby
|
71
79
|
require 'attribool'
|
72
80
|
|
73
81
|
class Person
|
74
|
-
|
82
|
+
extend Attribool
|
75
83
|
|
76
84
|
attr_accessor :name
|
77
|
-
bool_reader :name,
|
78
|
-
bool_reader :name, prefix: :has
|
85
|
+
bool_reader :name, method_name: :named?
|
79
86
|
end
|
80
87
|
|
81
88
|
person = Person.new
|
82
89
|
person.named?
|
83
|
-
person.has_name?
|
84
90
|
# false, because @name is nil.
|
85
91
|
|
86
92
|
person.name = 'John Smith'
|
87
93
|
person.named?
|
88
|
-
person.has_name?
|
89
94
|
# true, because @name is truthy.
|
90
95
|
```
|
91
96
|
|
@@ -94,11 +99,11 @@ person.has_name?
|
|
94
99
|
require 'attribool'
|
95
100
|
|
96
101
|
class Person
|
97
|
-
|
102
|
+
extend Attribool
|
98
103
|
|
99
104
|
attr_accessor :age
|
100
105
|
# In the condition lambdas, the argument refers to the attribute's value.
|
101
|
-
bool_reader :age,
|
106
|
+
bool_reader :age, method_name: :adult?, condition: ->(a) { a.to_i >= 18 }
|
102
107
|
end
|
103
108
|
|
104
109
|
person = Person.new
|
@@ -114,12 +119,40 @@ person.adult?
|
|
114
119
|
# true, because @age is greater than 18.
|
115
120
|
```
|
116
121
|
|
122
|
+
#### Assigning more than one bool_reader with a method name at once
|
123
|
+
```ruby
|
124
|
+
require 'attribool'
|
125
|
+
|
126
|
+
class Person
|
127
|
+
extend Attribool
|
128
|
+
|
129
|
+
attr_accessor :name, :age
|
130
|
+
# When creating multiple readers at once, if you want to specify a
|
131
|
+
# method_name, you must provide a Proc as the argument, where the attribute
|
132
|
+
# name is the argument.
|
133
|
+
bool_reader :age, :name, method_name: ->(m) { "has_#{m}?" }
|
134
|
+
end
|
135
|
+
|
136
|
+
person = Person.new
|
137
|
+
person.has_age?
|
138
|
+
person.has_name?
|
139
|
+
# Both false, because @age and @name are nil.
|
140
|
+
|
141
|
+
person.age = 10
|
142
|
+
person.has_age?
|
143
|
+
# true, because @age is not nil.
|
144
|
+
|
145
|
+
person.name = 'Bob'
|
146
|
+
person.has_name?
|
147
|
+
# true, because @name is not nil.
|
148
|
+
```
|
149
|
+
|
117
150
|
#### Standard bool_accessor
|
118
151
|
```ruby
|
119
152
|
require 'attribool'
|
120
153
|
|
121
154
|
class Person
|
122
|
-
|
155
|
+
extend Attribool
|
123
156
|
|
124
157
|
bool_accessor :living
|
125
158
|
end
|
@@ -134,6 +167,29 @@ person.living?
|
|
134
167
|
# Be aware -- if you pass anything truthy, it will be coerced to true!
|
135
168
|
```
|
136
169
|
|
170
|
+
#### Standard bool_writer
|
171
|
+
In most cases where you'd use a `bool_writer`, you'd probably want to just use
|
172
|
+
`bool_accessor`. This example is to show that, even when using `bool_accessor`,
|
173
|
+
the value is coerced to a boolean when the value is set by `bool_writer`.
|
174
|
+
```ruby
|
175
|
+
require 'attribool'
|
176
|
+
|
177
|
+
class Person
|
178
|
+
extend Attribool
|
179
|
+
|
180
|
+
attr_reader :living
|
181
|
+
bool_writer :living
|
182
|
+
end
|
183
|
+
|
184
|
+
person = Person.new
|
185
|
+
person.living
|
186
|
+
# nil
|
187
|
+
|
188
|
+
person.living = 'blah'
|
189
|
+
person.living
|
190
|
+
# true, because 'blah' was coerced into a boolean because strings are truthy.
|
191
|
+
```
|
192
|
+
|
137
193
|
## Reporting Bugs and Requesting Features
|
138
194
|
If you have an idea or find a bug, please [create an
|
139
195
|
issue](https://github.com/evanthegrayt/attribool/issues/new). Just make sure
|
@@ -144,4 +200,4 @@ Request.
|
|
144
200
|
I do these projects for fun, and I enjoy knowing that they're helpful to people.
|
145
201
|
Consider starring [the repository](https://github.com/evanthegrayt/attribool)
|
146
202
|
if you like it! If you love it, follow me [on
|
147
|
-
|
203
|
+
GitHub](https://github.com/evanthegrayt)!
|
data/attribool.gemspec
CHANGED
@@ -2,7 +2,7 @@ require_relative 'lib/attribool/version'
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |spec|
|
4
4
|
spec.name = 'attribool'
|
5
|
-
spec.version = Attribool::
|
5
|
+
spec.version = Attribool::VERSION
|
6
6
|
spec.authors = ['Evan Gray']
|
7
7
|
spec.email = 'evanthegrayt@vivaldi.net'
|
8
8
|
spec.license = 'MIT'
|
@@ -0,0 +1,62 @@
|
|
1
|
+
##
|
2
|
+
# Abstraction for an attribute to determine its name, reader, writer, and
|
3
|
+
# instance variable name.
|
4
|
+
class Attribool::Attribute
|
5
|
+
##
|
6
|
+
# The name of the attribute, without the leading "@".
|
7
|
+
#
|
8
|
+
# @return [String]
|
9
|
+
attr_reader :name
|
10
|
+
|
11
|
+
##
|
12
|
+
# The name of the instance variable for the attribute, with the leading "@".
|
13
|
+
#
|
14
|
+
# @return [String]
|
15
|
+
attr_reader :ivar
|
16
|
+
|
17
|
+
##
|
18
|
+
# The name of the reader for the attribute.
|
19
|
+
#
|
20
|
+
# @return [String]
|
21
|
+
attr_reader :reader
|
22
|
+
|
23
|
+
##
|
24
|
+
# The name of the writer for the attribute.
|
25
|
+
#
|
26
|
+
# @return [String]
|
27
|
+
attr_reader :writer
|
28
|
+
|
29
|
+
##
|
30
|
+
# Ensures that if multiple attributes are being defined, and +method_name+ is
|
31
|
+
# provided, that +method_name+ is a +Proc+.
|
32
|
+
#
|
33
|
+
# @param [Integer] number_of_attributes
|
34
|
+
#
|
35
|
+
# @param [String, Symbol, Proc] method_name
|
36
|
+
def self.validate_method_name(number_of_attributes, method_name)
|
37
|
+
if number_of_attributes > 1 && method_name && !method_name.is_a?(Proc)
|
38
|
+
raise ArgumentError, "Must use a Proc when creating multiple methods"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
##
|
43
|
+
# Create an Attribute. The attribute can either be a String or a Symbol, and
|
44
|
+
# can also start with an "@", or not.
|
45
|
+
#
|
46
|
+
# @param [String, Symbol] attribute
|
47
|
+
#
|
48
|
+
# @param [String, Symbol, Proc, nil] reader_name
|
49
|
+
def initialize(attribute, reader_name = nil)
|
50
|
+
attribute.to_s.tap do |a|
|
51
|
+
@ivar = a.start_with?('@') ? a : "@#{a}"
|
52
|
+
@name = @ivar.delete_prefix('@')
|
53
|
+
@reader =
|
54
|
+
case reader_name
|
55
|
+
when Proc then reader_name.call(name)
|
56
|
+
when nil then "#{name}?"
|
57
|
+
else reader_name.to_s
|
58
|
+
end
|
59
|
+
@writer = "#{name}="
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/lib/attribool/version.rb
CHANGED
@@ -9,7 +9,7 @@ module Attribool
|
|
9
9
|
# Major version.
|
10
10
|
#
|
11
11
|
# @return [Integer]
|
12
|
-
MAJOR =
|
12
|
+
MAJOR = 1
|
13
13
|
|
14
14
|
##
|
15
15
|
# Minor version.
|
@@ -21,14 +21,36 @@ module Attribool
|
|
21
21
|
# Patch version.
|
22
22
|
#
|
23
23
|
# @return [Integer]
|
24
|
-
PATCH =
|
24
|
+
PATCH = 1
|
25
|
+
|
26
|
+
##
|
27
|
+
# Version as +[MAJOR, MINOR, PATCH]+
|
28
|
+
#
|
29
|
+
# @return [Array]
|
30
|
+
def self.to_a
|
31
|
+
[MAJOR, MINOR, PATCH]
|
32
|
+
end
|
25
33
|
|
26
34
|
##
|
27
35
|
# Version as +MAJOR.MINOR.PATCH+
|
28
36
|
#
|
29
37
|
# @return [String]
|
30
38
|
def self.to_s
|
31
|
-
|
39
|
+
to_a.join('.')
|
40
|
+
end
|
41
|
+
|
42
|
+
##
|
43
|
+
# Version as +{major: MAJOR, minor: MINOR, patch: PATCH}+
|
44
|
+
#
|
45
|
+
# @return [Hash]
|
46
|
+
def self.to_h
|
47
|
+
%i[major minor patch].zip(to_a).to_h
|
32
48
|
end
|
33
49
|
end
|
50
|
+
|
51
|
+
##
|
52
|
+
# The version, as a string.
|
53
|
+
#
|
54
|
+
# @return [String]
|
55
|
+
VERSION = Version.to_s.freeze
|
34
56
|
end
|
data/lib/attribool.rb
CHANGED
@@ -1,70 +1,66 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative 'attribool/version'
|
4
|
+
require_relative 'attribool/attribute'
|
5
|
+
|
3
6
|
##
|
4
|
-
# Adds macros
|
7
|
+
# Adds macros for dealing with boolean attributes.
|
5
8
|
module Attribool
|
6
|
-
def self.included(klass) # :nodoc:
|
7
|
-
klass.extend(ClassMethods)
|
8
|
-
end
|
9
|
-
|
10
9
|
##
|
11
|
-
#
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
allow_nil: true,
|
29
|
-
condition: nil,
|
30
|
-
prefix: nil,
|
31
|
-
method: nil
|
32
|
-
)
|
33
|
-
method ||= "#{attribute}?"
|
34
|
-
method = "#{prefix}_#{method}" if prefix
|
35
|
-
define_method(method) do
|
36
|
-
ivar = instance_variable_get("@#{attribute}")
|
37
|
-
raise TypeError, "#{attribute} is nil" if ivar.nil? && !allow_nil
|
10
|
+
# Creates methods that return a boolean for attributes that may or may not be
|
11
|
+
# booleans themselves. Multiple readers can be created at once
|
12
|
+
#
|
13
|
+
# @param [Symbol, String] *attributes
|
14
|
+
#
|
15
|
+
# @kwarg [Boolean] allow_nil
|
16
|
+
#
|
17
|
+
# @kwarg [Proc] condition
|
18
|
+
#
|
19
|
+
# @kwarg [Symbol, String, Proc] method_name
|
20
|
+
def bool_reader(
|
21
|
+
*attributes,
|
22
|
+
allow_nil: true,
|
23
|
+
condition: nil,
|
24
|
+
method_name: nil
|
25
|
+
)
|
26
|
+
Attribute.validate_method_name(attributes.size, method_name)
|
38
27
|
|
39
|
-
|
28
|
+
attributes.map { |a| Attribute.new(a, method_name) }.each do |attribute|
|
29
|
+
define_method(attribute.reader) do
|
30
|
+
value = instance_variable_get(attribute.ivar)
|
31
|
+
raise TypeError, "#{attribute.ivar} is nil" if value.nil? && !allow_nil
|
32
|
+
|
33
|
+
condition ? condition.call(value) : !!(value)
|
40
34
|
end
|
41
35
|
end
|
36
|
+
end
|
42
37
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
38
|
+
##
|
39
|
+
# Creates a writer for boolean attributes. Always coerces to boolean based
|
40
|
+
# on truthiness.
|
41
|
+
#
|
42
|
+
# @param [Symbol, String] *attributes
|
43
|
+
#
|
44
|
+
# @kwarg [Boolean] strict
|
45
|
+
def bool_writer(*attributes, strict: false)
|
46
|
+
attributes.map { |a| Attribute.new(a) }.each do |attribute|
|
47
|
+
define_method(attribute.writer) do |v|
|
52
48
|
if strict && ![TrueClass, FalseClass].include?(v.class)
|
53
49
|
raise ArgumentError, 'Argument must be a boolean'
|
54
50
|
end
|
55
51
|
|
56
|
-
instance_variable_set(
|
52
|
+
instance_variable_set(attribute.ivar, !!v)
|
57
53
|
end
|
58
54
|
end
|
55
|
+
end
|
59
56
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
end
|
57
|
+
##
|
58
|
+
# Creates a simple reader and writer for booleans. This should only be used
|
59
|
+
# when the attribute should only ever be +true+ or +false+.
|
60
|
+
#
|
61
|
+
# @param [Symbol, String] *attributes
|
62
|
+
def bool_accessor(*attributes)
|
63
|
+
bool_reader(*attributes)
|
64
|
+
bool_writer(*attributes)
|
69
65
|
end
|
70
66
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: attribool
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Evan Gray
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-01-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -79,6 +79,7 @@ files:
|
|
79
79
|
- Rakefile
|
80
80
|
- attribool.gemspec
|
81
81
|
- lib/attribool.rb
|
82
|
+
- lib/attribool/attribute.rb
|
82
83
|
- lib/attribool/version.rb
|
83
84
|
homepage: https://github.com/evanthegrayt/attribool
|
84
85
|
licenses:
|