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