def evaluate(expression, user, resource)
      Array(expression).flat_map do |el|
        if expression?(el)
          cache.fetch(el) {
            type, *ary  = el.split('::')
            if type == 'user'
              Array(ary.inject(user) do |rval, attr|
                rval.freeze.public_send(attr)
              end)
            elsif type == 'resource'
              Array(ary.inject(resource) do |rval, attr|
                rval.freeze.public_send(attr)
              end)
            else
              raise "Expected #{type} to be 'resource' or 'user'"
            end
          }
        else
          el
        end
      end
    end
def evaluate(expression, user, resource)
      Array(expression).flat_map do |el|
        if expression?(el)
          cache.fetch(el) {
            type, *ary  = el.split('::')
            if type == 'user'
              Array(ary.inject(user) do |rval, attr|
                rval.freeze.public_send(attr)
              end)
            elsif type == 'resource'
              Array(ary.inject(resource) do |rval, attr|
                rval.freeze.public_send(attr)
              end)
            else
              raise "Expected #{type} to be 'resource' or 'user'"
            end
          }
        else
          el
        end
      end
    end
*Safely* evaluate a conditional expression

 @note
 This does not guarantee that conditions are correctly specified.
 For example, 'user:::manager' will not resolve to anything, and
 and an exception will *not* be raised. The same goes for 'user:::' and
 'user:id'.

 @param expressions [Array<String, Object>, String, Object] an array or
 a single expression. This represents either an immediate value (e.g.,
 '1', 99) or a valid expression that can be interpreted (see example)

 @example
   ['user::manager_id']     #=> [1]
   ['user::role_ids']       #=> [1,2,3,4]
   ['resource::manager_id'] #=> [1]
   [1,2,3,4]                #=> [1,2,3,4]
   'user::id'               #=> [1]
   'resource::id'           #=> [2]

 @return [Array<Object>] a collection of 0 or more objects
 representing attributes on the user or resource