# encoding: utf-8 module Policy # Interface for the class that follows policies module Follower # Methods to be added to the follower class module ClassMethods # Declares a policy to be followed # # Mutates the object by adding an item to its {#policies}. # # @param [Symbol] name # # @return [:follows_policy] the name of the method def follows_policy(name) policies.add name :follows_policy end # Declares policies to be followed # # Mutates the object by adding items to its {#policies}. # # @param [Symbol, Array] names # # @return [:follows_policies] the name of the method def follows_policies(*names) names.each(&method(:follows_policy)) :follows_policies end # @!attribute [r] policies # The collection of followed policies # # @return [Policy::Follower::Policies] def policies @policies ||= Policies.new(self) end end # Checks whether an object follows all its policies or subset of policies # # @overload follow_policies?() # Checks whether an object follows all registered policies # # @overload follow_policies?(names) # Checks whether an object follows given policies # # @param [#to_sym, Array<#to_sym>] names # # @raise [Policy::Follower::NameError] # if the policy is not registered by name # # @raise [NoMethodError] # if the name not implemented as follower's instance method # @raise [ViolationError] # if the policy is violated by the follower # # @return [true] if no exception being raised def follow_policies?(*names) __policies__ .subset(names) # raises NameError .map(&method(:__send__)) # raises NoMethodError .each(&method(:__validate_policy__)) # raises ViolationError true end # Checks whether an object follows given policy # # @param [#to_sym] name # the name of the policy to follow # # @raise (see #follow_policies?) # # @return (see #follow_policies?) def follow_policy?(name) follow_policies? name end # @private def self.included(klass) klass.instance_eval { extend ClassMethods } end private def __validate_policy__(policy) fail ViolationError.new(self, policy) unless policy.valid? end def __policies__ self.class.policies end end # module Follower end # module Policy