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