attribool 0.1.0 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
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: