Module: BanditMask::Banditry

Defined in:
lib/banditmask/banditry.rb

Instance Method Summary collapse

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


32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/banditmask/banditry.rb', line 32

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

    define_method :has? do |*bits|
      cls.new(send(attribute)).include? *bits
    end
  end
end