Module: BanditMask::Banditry

Defined in:
lib/banditmask/banditry.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.extended(cls) ⇒ Object

:nodoc:



5
6
7
# File 'lib/banditmask/banditry.rb', line 5

def self.extended(cls) # :nodoc:
  cls.extend Forwardable
end

Instance Method Details

#bandit_mask(attribute, as:, with: BanditMask) ⇒ Object

Creates wrapper methods for reading and writing the bitmask stored in attribute using the class with. with defaults to BanditMask, but you can (and probably) should define your own class descending from BanditMask to fill this role. The name of the accessor methods will be derived from as, e.g., if as is :foo, the reader method will be :foo and the writer will be :foo=.

The reader method will call BanditMask#bits to get an array of the enabled bit names represented by attribute.

The writer method will replace the current bitmask with an Integer representation of a new BanditMask built up using BanditMask#<<.

In addition to the accessor methods, a method named has? will be added which delegates to the BanditMask#include?.

class ThingMask < BanditMask
  # ...
  # bit :foo, 0b1
  # ...
end

class Thing
  attr_accessor :bitmask

  extend BanditMask::Banditry
  bandit_mask :bitmask, as: :bits, with: ThingMask
end


38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/banditmask/banditry.rb', line 38

def bandit_mask(attribute, as:, with: BanditMask)
  cls = with
  wrapper = as

  class_eval do
    ##
    # A reader method which instances a new BanditMask object and calls
    # BanditMask#bits.
    define_method wrapper do
      cls.new(send(attribute)).bits
    end

    define_method :"#{wrapper}=" do |bits|
      mask = bits.reduce(cls.new) { |mask, bit| mask << bit }
      send :"#{attribute}=", Integer(mask)
    end

    def_delegator wrapper, :include?, :has?
  end
end