Sha256: fa4e356bee3458396d8d7b1b9c95eaf3602c5a5ad7163a6f73369ed3303ff513

Contents?: true

Size: 1.79 KB

Versions: 1

Compression:

Stored size: 1.79 KB

Contents

require 'forwardable'

class BanditMask
  module Banditry
    def self.extended(cls) # :nodoc:
      cls.extend Forwardable
    end

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

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
banditmask-0.2.0 lib/banditmask/banditry.rb