Easily create attr (attribute) methods that end with question marks (?) for booleans/predicates.
require 'attr_bool'
#using AttrBool::Ref # Can use refinements instead of `extend AttrBool::Ext`.
class TheTodd
extend AttrBool::Ext
attr_accessor? :headband
attr_reader? :banana_hammock
attr_writer? :high_five
# Can do DSL chaining.
protected attr_accessor? :carla_kiss, :elliot_kiss
# Can force bool values (i.e., only `true` or `false`).
attr_bool :bounce_pecs # Accessor.
attr_bool? :cat_fight # Reader.
attr_bool! :hot_tub # Writer.
end
todd = TheTodd.new
puts todd.headband?
puts todd.banana_hammock?
puts todd.bounce_pecs?
puts todd.cat_fight?Features:
- Can use multiple symbols and/or strings.
- Can force bool values.
- Can define custom logic with a block/proc/lambda.
- Can do DSL chaining, just like the core
attrmethods that return an array of the new method names. - Can use refinements (
using AttrBool::Ref) instead ofextend. - Fails fast if an instance variable name is invalid (if you don't use a block/proc/lambda).
Anti-features:
- No default values.
- Initialize your instance variables in
def initializelike normal. - Using default values has performance/memory issues and other drawbacks, so better to just match the core
attrmethods.
- Initialize your instance variables in
- Uses inner
AttrBool::Ext&AttrBool::Refinstead ofAttrBool.- Some gems use the
extend AttrBool(top module) pattern, but this includes theVERSIONconstant in all of your classes/modules.
- Some gems use the
- Doesn't monkey-patch the core class/module by default.
- If desired for apps/scripts, you still can with
require 'attr_bool/core_ext', but not recommended for libraries.
- If desired for apps/scripts, you still can with
// Similar Projects
Create a discussion or an issue to let me know to add your project.
| Gem Name | Code | Example |
|---|---|---|
| attr_asker | GitHub | attr_asker :winning |
| attr_boolean | GitHub | attr_boolean :winning, default: true |
| attr_setting | GitHub | attr_setting :winning, true |
| attribool | GitHub | bool_reader :winning |
| attribute_boolean | GitHub | attr_boolean :winning |
| attribute_predicates | GitHub | attr :winning, true |
| boolean_accessor | GitHub | battr_accessor :winning |
| named_accessors | GitHub | named_reader :winning, as: :winning? |
| predicateable | GitHub | predicate :wins, [:losing, :winning] |
| predicates | GitHub | predicate :winning? |
| property-accessor | GitHub | property(:winning) { get(:winning?); default { true } } |
| question_mark_methods | GitHub | add_question_mark_methods winning?: :winning |
| wannabe_bool | GitHub | attr_wannabe_bool :winning |
| wardrobe | GitHub | attribute :winning, Wardrobe::Boolean, default: true |
Searches:
| Site | Searches |
|---|---|
| The Ruby Toolbox | 1, 2 |
| RubyGems.org | 1, 2 |
// Setup
Pick your poison...
With the RubyGems package manager:
gem install attr_boolOr in your Gemspec:
spec.add_dependency 'attr_bool', '~> X.X.X'Or in your Gemfile:
# Pick your poison...
gem 'attr_bool', '~> X.X.X'
gem 'attr_bool', git: 'https://github.com/esotericpig/attr_bool.git'Or from source:
git clone --depth 1 'https://github.com/esotericpig/attr_bool.git'
cd attr_bool
bundle install
bundle exec rake install:local// Usage
You can either add using AttrBool::Ref in your class/module/file, add extend AttrBool::Ext in your class/module, or include require 'attr_bool/core_ext'.
require 'attr_bool'
class TheTodd
extend AttrBool::Ext
#using AttrBool::Ref # Can use refinements instead.
# Can use multiple symbols and/or strings.
attr_accessor? :flexing, 'bounce_pecs'
# Can do DSL chaining.
protected attr_accessor? :high_five, 'fist_bump'
# Can force bool values (i.e., only `true` or `false`).
attr_bool :carla_kiss # Accessor.
attr_bool? :elliot_kiss # Reader.
attr_bool! :thumbs_up # Writer.
# Can do custom logic with a block/proc/lambda.
attr_reader?(:cat_fights) { @cat_fights % 69 }
attr_writer?(:hot_surgeries) { |count| @hot_surgeries += count }
attr_accessor? :headband, 'banana_hammock',
reader: -> { @wearing == :flaming },
writer: ->(value) { @wearing = value }
endIf you don't want to have to add extend AttrBool::Ext to every inner class/module (within the same file), then you can simply refine the outer module or the file:
require 'attr_bool'
#using AttrBool::Ref # Can refine the entire file instead (doesn't affect other files).
module TheToddMod
using AttrBool::Ref
class TheTodd
attr_bool :banana_hammock
end
class TheToddBod
attr_bool :bounce_pecs
end
endIf you only have an app/script (not a library), then you can simply include require 'attr_bool/core_ext' to monkey-patch the core class & module:
require 'attr_bool/core_ext'
class TheTodd
attr_bool :banana_hammock
end/// RuboCop
RuboCop might complain about Layout/EmptyLinesAroundAttributeAccessor:
class TheTodd
attr_accessor? :banana_hammock
attr_accessor :headband
attr_accessor? :bounce_pecs
endYou can either adjust this Cop accordingly or disable it:
Layout/EmptyLinesAroundAttributeAccessor:
#Enabled: false
AllowedMethods:
- attr_accessor?
- attr_reader?
- attr_writer?
- attr_bool
- attr_bool?
- attr_bool!/// YARDoc
Here are some examples of how to document the methods in YARDoc:
attr_accessor? :winning # @!attribute [rw] winning=(value),winning?
attr_reader? :running # @!attribute [r] running?
# @!attribute [r] can_swim?
# @return [true,false] can you swim in it?
# @!attribute [r] can_wink?
# @return [true,false] can you wink at pretty people?
attr_reader? :can_swim,:can_wink
# @!attribute [rw] princess=(value),princess?
# @param value [true,false] this is Ms. Consuela or not!
# @return [true,false] is this Ms. Consuela?
# @!attribute [rw] crap_bag=(value),crap_bag?
# @param value [true,false] this is Mr. Crap Bag or not!
# @return [true,false] is this Mr. Crap Bag?
attr_accessor? :princess,:crap_bag
# @overload in_fashion?
# @return [true,false] whether it's fashionable right now
# @overload in_fashion=(value)
# Make it in or out of fashion!
attr_accessor? :in_fashion
# @!group My Attrs
# @!attribute [r] in_season?
attr_reader? :in_season
# @!attribute [r] can_wash?
attr_reader? :can_wash
# @!endgroupFurther reading:
// Hacking
git clone 'https://github.com/esotericpig/attr_bool.git'
cd attr_bool
bundle install
bundle exec rake -TRun tests:
bundle exec rake testGenerate doc:
bundle exec rake docInstall locally:
bundle exec rake install:local/// Benchmarks
Benchmarks are kind of meaningless, but after playing around with some, I found the following to be true on my system:
define_method()is faster thanclass/module_eval().? true : false(ternary operator) is faster than!!(surprisingly).
Therefore, AttrBool uses the "faster" ones found.
To run these on your system:
bundle exec rake bench// License
AttrBool (https://github.com/esotericpig/attr_bool)
Copyright (c) 2020-2025 Bradley Whited
MIT License