lib/banditry/bandit_mask.rb in banditry-0.4.0 vs lib/banditry/bandit_mask.rb in banditry-0.5.0
- old
+ new
@@ -1,7 +1,11 @@
+# frozen-string-literal: true
+
module Banditry
class BanditMask
+ include Enumerable
+
attr_reader :bitmask
def initialize(bitmask = nil) # :nodoc:
@bitmask = bitmask || 0b0
end
@@ -26,11 +30,11 @@
# bit :read, 0b001
# bit :write, 0b010
# bit :execute, 0b100
# end
def self.bit(name, value)
- bits.update name => value
+ bits.update name.to_sym => value
end
##
# Returns integer value of current bitmask.
def to_i
@@ -51,10 +55,29 @@
self.class.bits.select { |bit, _| include? bit }.keys
end
alias_method :to_a, :bits
##
+ # Delegates to #bits.
+ #
+ # class MyMask < Banditry::BanditMask
+ # bit :read, 0b001
+ # bit :write, 0b010
+ # bit :execute, 0b100
+ # end
+ #
+ # mask = MyMask.new 0b101
+ # mask.each do |bit|
+ # # => :read
+ # # => :execute
+ # end
+ # mask.each # => #<Enumerator: ...>
+ def each(&block)
+ bits.each(&block)
+ end
+
+ ##
# Enables the bit named +bit+. Returns +self+, so calls to #<< can be
# chained. (Think Array#<<.) Raises +ArgumentError+ if +bit+ does not
# correspond to a bit that was previously defined with
# Banditry::BanditMask.bit.
#
@@ -113,10 +136,17 @@
end
alias_method :eql?, :==
##
+ # Returns +true+ if bitmask is zero (no bits are enabled) and +false+
+ # otherwise.
+ def empty?
+ bitmask.zero?
+ end
+
+ ##
# Returns an object hash. Two Banditry::BanditMask objects have identical
# hashes if they have identical bitmasks and are instances of the same
# class.
def hash
[bitmask, self.class].hash
@@ -151,10 +181,11 @@
##
# Returns the integer value for the bit named +bit+. Raises +ArgumentError+
# if +bit+ has not been previously defined with Banditry::BanditMask.bit.
def bit_value(bit)
- self.class.bits.fetch(bit) do
+ bit = bit.to_sym
+ self.class.bits.fetch bit do
raise ArgumentError, "undefined bit: #{bit.inspect}"
end
end
end
end