attribool 0.1.0 → 1.0.3

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: f04da5ae0d24a9e980b51a244c7d83ab90b6f4b3d288a49ab069397be78fe3d4
4
- data.tar.gz: 5145d0dea86d0341d5bdbb64ae240647caca668eca6f72122bb1cf831a273ef3
3
+ metadata.gz: eb6bff0b78f856fe87c3d101b3f2eaf4eeeb49fcc9d5a7171857df555ec93125
4
+ data.tar.gz: fcf0a984bd435bd05c0b6039201419fb5aa3c40df94efb33e288d1ff069ca57d
5
5
  SHA512:
6
- metadata.gz: c048e38a1a380785c5fdb7198913cb2aa686ea47f955ab649e004cf77e8e3fea08be1857a3d89e3da3647d788b0944cffceabdbbf0a5b85db560949426e60525
7
- data.tar.gz: 3f522acba694671f5e8d7bf4a12221d9ac1edef9e538bf943683119c9346a68340550bee719db1167a9104ced50d9b2869e89245ec820ee5c4bae6542a6f00a2
6
+ metadata.gz: 47e07045578ba1f698eebdcfc72d9d0de7d634f2d8950b7067bb6c4c74baabbbadf90e92e4392872c8992c09e2954833daae5b8a496f7d01efc7e2537e8f392b
7
+ data.tar.gz: 70cf40cf0102b2def2b68b9c5b51103bbad23ebd9a8a01d812f6a41a766ae3fd007455ed4842f5000298d147ded173b09fd1d3b6bf6ecedf8b7ad6fd9b9f6ae2
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- attribool (0.1.0)
4
+ attribool (1.0.3)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -4,17 +4,18 @@
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
5
 
6
6
  Ruby macros for creating boolean methods for attributes that may or may not be
7
- booleans themselves. This is done via coercion based on truthiness.
7
+ booleans themselves. This is done via either coercion based on truthiness, or a
8
+ user-defined condition.
8
9
 
9
10
  For example, if you have an attribute of `@name`, and you want to know if
10
11
  `@name` is not `nil`, you can declare `bool_reader :name`, which will define the
11
12
  method `name?`. This method will return true if `@name` is truthy.
12
13
 
13
14
  The `bool_reader` also comes with some handy options. For example, you can
14
- [define a method name](#a-bool_reader-with-method-name-or-prefix) that makes
15
+ [define a method name](#a-bool_reader-with-method-name) that makes
15
16
  more sense. Using the same example as above, if your attribute is `@name`, but
16
17
  you'd like for your boolean method to be called `named?`, you can use
17
- `bool_reader :name, method: :named?`.
18
+ `bool_reader :name, method_name: :named?`.
18
19
  [Conditionals](#a-bool_reader-with-method-name-and-conditional) can also be set
19
20
  with lambdas via the `condition:` keyword argument.
20
21
 
@@ -57,7 +58,9 @@ class Person
57
58
  attr_accessor :name
58
59
  bool_reader :name
59
60
  # OR
60
- bool_reader :@name
61
+ # bool_reader :@name
62
+ # bool_reader 'name'
63
+ # bool_reader '@name'
61
64
  end
62
65
 
63
66
  person = Person.new
@@ -71,7 +74,7 @@ person.name?
71
74
  # true, because @name is truthy.
72
75
  ```
73
76
 
74
- #### A bool_reader with method name or prefix
77
+ #### A bool_reader with method name
75
78
  ```ruby
76
79
  require 'attribool'
77
80
 
@@ -79,18 +82,15 @@ class Person
79
82
  extend Attribool
80
83
 
81
84
  attr_accessor :name
82
- bool_reader :name, method: :named?
83
- bool_reader :name, prefix: :has
85
+ bool_reader :name, method_name: :named?
84
86
  end
85
87
 
86
88
  person = Person.new
87
89
  person.named?
88
- person.has_name?
89
90
  # false, because @name is nil.
90
91
 
91
92
  person.name = 'John Smith'
92
93
  person.named?
93
- person.has_name?
94
94
  # true, because @name is truthy.
95
95
  ```
96
96
 
@@ -103,7 +103,7 @@ class Person
103
103
 
104
104
  attr_accessor :age
105
105
  # In the condition lambdas, the argument refers to the attribute's value.
106
- bool_reader :age, method: :adult?, condition: ->(a) { a.to_i >= 18 }
106
+ bool_reader :age, method_name: :adult?, condition: ->(a) { a.to_i >= 18 }
107
107
  end
108
108
 
109
109
  person = Person.new
@@ -119,6 +119,34 @@ person.adult?
119
119
  # true, because @age is greater than 18.
120
120
  ```
121
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
+
122
150
  #### Standard bool_accessor
123
151
  ```ruby
124
152
  require 'attribool'
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ ##
4
+ # Abstraction for an attribute to determine its name, reader, writer, and
5
+ # instance variable name.
6
+ class Attribool::Attribute
7
+ ##
8
+ # The name of the attribute, without the leading "@".
9
+ #
10
+ # @return [String]
11
+ attr_reader :name
12
+
13
+ ##
14
+ # The name of the instance variable for the attribute, with the leading "@".
15
+ #
16
+ # @return [String]
17
+ attr_reader :ivar
18
+
19
+ ##
20
+ # The name of the reader for the attribute.
21
+ #
22
+ # @return [String]
23
+ attr_reader :reader
24
+
25
+ ##
26
+ # The name of the writer for the attribute.
27
+ #
28
+ # @return [String]
29
+ attr_reader :writer
30
+
31
+ class << self
32
+ ##
33
+ # Ensures that if multiple attributes are being defined, and +method_name+
34
+ # is provided, that +method_name+ is a +Proc+.
35
+ #
36
+ # @param [Integer] number_of_attributes
37
+ #
38
+ # @param [String, Symbol, Proc] method_name
39
+ def validate_method_name(method_name, number_of_attributes)
40
+ return if number_of_attributes == 1 || nil_or_proc?(method_name)
41
+
42
+ raise ArgumentError, "Must use a Proc when creating multiple methods"
43
+ end
44
+
45
+ private
46
+
47
+ def nil_or_proc?(method_name) # :nodoc:
48
+ method_name.nil? || (method_name.is_a?(Proc) && method_name.arity == 1)
49
+ end
50
+ end
51
+
52
+ ##
53
+ # Create an Attribute. The attribute can either be a String or a Symbol, and
54
+ # can also start with an "@", or not.
55
+ #
56
+ # @param [String, Symbol] attribute
57
+ #
58
+ # @param [String, Symbol, Proc, nil] reader_name
59
+ def initialize(attribute, reader_name = nil)
60
+ attribute.to_s.tap do |a|
61
+ @ivar = a.start_with?('@') ? a : "@#{a}"
62
+ @name = @ivar.delete_prefix('@')
63
+ @reader =
64
+ case reader_name
65
+ when Proc then reader_name.call(name)
66
+ when nil then "#{name}?"
67
+ else reader_name.to_s
68
+ end
69
+ @writer = "#{name}="
70
+ end
71
+ end
72
+ end
@@ -9,19 +9,19 @@ module Attribool
9
9
  # Major version.
10
10
  #
11
11
  # @return [Integer]
12
- MAJOR = 0
12
+ MAJOR = 1
13
13
 
14
14
  ##
15
15
  # Minor version.
16
16
  #
17
17
  # @return [Integer]
18
- MINOR = 1
18
+ MINOR = 0
19
19
 
20
20
  ##
21
21
  # Patch version.
22
22
  #
23
23
  # @return [Integer]
24
- PATCH = 0
24
+ PATCH = 3
25
25
 
26
26
  ##
27
27
  # Version as +[MAJOR, MINOR, PATCH]+
@@ -48,5 +48,9 @@ module Attribool
48
48
  end
49
49
  end
50
50
 
51
+ ##
52
+ # The version, as a string.
53
+ #
54
+ # @return [String]
51
55
  VERSION = Version.to_s.freeze
52
56
  end
data/lib/attribool.rb CHANGED
@@ -1,39 +1,37 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'attribool/version'
4
+ require_relative 'attribool/attribute'
4
5
 
5
6
  ##
6
- # Adds macros and methods for dealing with boolean attributes.
7
+ # Adds macros for dealing with boolean attributes.
7
8
  module Attribool
8
9
  ##
9
- # Creates a method that returns a boolean for attributes that may or may
10
- # not be booleans themselves.
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
11
12
  #
12
- # @param [Symbol, String] attribute
13
+ # @param [Symbol, String] *attributes
13
14
  #
14
- # @kwarg [Boolean] allow_nil:
15
+ # @kwarg [Boolean] allow_nil
15
16
  #
16
- # @kwarg [Lambda] condition:
17
+ # @kwarg [Proc] condition
17
18
  #
18
- # @kwarg [Symbol, String] method:
19
- #
20
- # @kwarg [Symbol, String] prefix:
19
+ # @kwarg [Symbol, String, Proc] method_name
21
20
  def bool_reader(
22
- attribute,
21
+ *attributes,
23
22
  allow_nil: true,
24
23
  condition: nil,
25
- prefix: nil,
26
- method: nil
24
+ method_name: nil
27
25
  )
28
- attribute = attribute.to_s
29
- attribute = attribute.start_with?('@') ? attribute : "@#{attribute}"
30
- method ||= "#{attribute.delete_prefix('@')}?"
31
- method = "#{prefix}_#{method}" if prefix
32
- define_method(method) do
33
- ivar = instance_variable_get(attribute)
34
- raise TypeError, "#{attribute} is nil" if ivar.nil? && !allow_nil
26
+ Attribute.validate_method_name(method_name, attributes.size)
27
+
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
35
32
 
36
- condition ? condition.call(ivar) : !!(ivar)
33
+ condition ? condition.call(value) : !!(value)
34
+ end
37
35
  end
38
36
  end
39
37
 
@@ -41,18 +39,18 @@ module Attribool
41
39
  # Creates a writer for boolean attributes. Always coerces to boolean based
42
40
  # on truthiness.
43
41
  #
44
- # @param [Symbol, String] attribute
42
+ # @param [Symbol, String] *attributes
45
43
  #
46
- # @kwarg [Boolean] strict:
47
- def bool_writer(attribute, strict: false)
48
- attribute = attribute.to_s
49
- attribute = attribute.start_with?('@') ? attribute : "@#{attribute}"
50
- define_method("#{attribute.delete_prefix('@')}=") do |v|
51
- if strict && ![TrueClass, FalseClass].include?(v.class)
52
- raise ArgumentError, 'Argument must be a boolean'
53
- end
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|
48
+ if strict && ![TrueClass, FalseClass].include?(v.class)
49
+ raise ArgumentError, 'Argument must be a boolean'
50
+ end
54
51
 
55
- instance_variable_set(attribute, !!v)
52
+ instance_variable_set(attribute.ivar, !!v)
53
+ end
56
54
  end
57
55
  end
58
56
 
@@ -60,9 +58,9 @@ module Attribool
60
58
  # Creates a simple reader and writer for booleans. This should only be used
61
59
  # when the attribute should only ever be +true+ or +false+.
62
60
  #
63
- # @param [Symbol, String] attribute
64
- def bool_accessor(attribute)
65
- bool_reader(attribute)
66
- bool_writer(attribute)
61
+ # @param [Symbol, String] *attributes
62
+ def bool_accessor(*attributes)
63
+ bool_reader(*attributes)
64
+ bool_writer(*attributes)
67
65
  end
68
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: 0.1.0
4
+ version: 1.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Evan Gray
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-12-21 00:00:00.000000000 Z
11
+ date: 2022-01-29 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: