Project

attr_bool

0.0
No release in over 3 years
Finally attr_accessor? & attr_reader? with question marks for booleans/predicates!? To get started, pick one: (1) in your class/module, add `using AttrBool::Ref`, or (2) in your class/module, add `extend AttrBool::Ext`, or (3) in your app/script (not library), include `require 'attr_bool/core_ext'`. Now simply use any: [ attr_accessor?, attr_reader?, attr_writer?, attr_bool, attr_bool?, attr_bool! ]. Keywords: attr, attribute, attributes, bool, boolean, booleans, predicate, predicates
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
 Dependencies
 Project Readme

AttrBool

Gem Version Tests Status Source Code Changelog License

Easily create attr (attribute) methods that end with question marks (?) for booleans/predicates.

require 'attr_bool'

class TheTodd
  extend AttrBool::Ext
  #using AttrBool::Ref  # Can use refinements instead.

  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.
  • Can do DSL chaining, just like the core attr methods that return an array of the new method names.
  • Can use refinements (using AttrBool::Ref) instead of extend.
  • Fails fast if an instance variable name is invalid (if you don't use a block/proc).

Anti-features:

  • No default values.
    • Initialize your instance variables in def initialize like normal.
    • Using default values has performance/memory issues and other drawbacks, so better to just match the core attr methods.
  • Uses inner AttrBool::Ext & AttrBool::Ref instead of AttrBool.
    • Some gems use the extend AttrBool (top module) pattern, but this includes VERSION in all of your classes/modules.
  • 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.

// Contents

  • Similar Projects
  • Setup
  • Usage
    • RuboCop
    • YARDoc
  • Hacking
    • Benchmarks
  • License

// 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_bool

Or in your Gemspec:

spec.add_dependency 'attr_bool', '~> X.X'

Or in your Gemfile:

# Pick your poison...
gem 'attr_bool', '~> 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 extend AttrBool::Ext in your class/module, add using AttrBool::Ref 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 do custom logic.
  attr_accessor? :headband, 'banana_hammock',
                 reader: -> { @wearing == :flaming },
                 writer: ->(value) { @wearing = value }

  attr_reader?(:cat_fights)    { @cat_fights % 69 }
  attr_writer?(:hot_surgeries) { |count| @hot_surgeries += count }

  # 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.
end

If 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
end

If 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
end

You can either disable this Cop or adjust it accordingly:

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
# @!endgroup

Further reading:

// Hacking

git clone 'https://github.com/esotericpig/attr_bool.git'
cd attr_bool
bundle install
bundle exec rake -T

Run tests:

bundle exec rake test

Generate doc:

bundle exec rake doc

Install 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 than class/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