Skip to content

esotericpig/attr_bool

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

82 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

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' #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 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/lambda).

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 the VERSION constant 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

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.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 } 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 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 # @!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

About

πŸ”°πŸ±β“ Finally attr_accessor & attr_reader with question marks for booleans/predicates!?

Topics

Resources

License

Stars

Watchers

Forks

Contributors

Languages