Skip to content

Instantly share code, notes, and snippets.

@wereHamster
Created July 23, 2012 12:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wereHamster/3163506 to your computer and use it in GitHub Desktop.
Save wereHamster/3163506 to your computer and use it in GitHub Desktop.
package models
/* A scope defines what actions a user can perform. Each possible action is
* assigned a bit in a bitset (up to 64 different actions are possible in
* theory, though we only store a limited number of bits in the database).
*/
sealed case class Scope(value: Long) {
/* Combine two scopes. Does a bitwise or of the two bitsets and returns a
* new scope.
*/
def |(x: Scope): Scope =
Scope(this.value | x.value)
/* Return true if `this` includes the given scope. */
def includes(x: Scope): Boolean =
(this.value & x.value) == x.value
}
object Empty extends Scope(0)
object All extends Scope(0xFFFFFFFF)
object Read extends Scope(1)
object Write extends Scope(2)
object Query extends Scope(4)
@meiersi
Copy link

meiersi commented Jul 23, 2012

Hmm...to me it seems that the abstraction is leaking too many implementation details. Abstractly, what you are modelling is that a Scope is a finite set of Actions. For each Action you can test whether it is a member of a Scope or not. Scopes offer the usual set operations.

Your construction of offering an Empty scope and an All scope corresponds to the observation that Scopes also form a bounded lattice where join is interpreted as a set union, meet as set intersection, top as the set of all actions, and bottom as the empty set of actions.

I'm not advocating that you should use this terminology. It might scare some people ;-) The benefit of making this connection is that you immediately get all theorems and algorithms that work with bounded lattices for free. Moreover, it becomes easy to see what operations make sense to offer. In Haskell, you'd additionally make an instance of BoundedLattice and get the operations like meets for free. For example, meets :: [Scope] -> Scope would correspond to taking the least privileges of a list of scopes. You'd use that for example when computing the scope of a list of objects, which you edit jointly.

Anyways, I think that your documentation should mention the 64bit limitation at most as a side-note. The key abstraction is that of a bounded lattice of actions that you can perform and not that of a list of at most 64 bits that denote actions that you can perform.

@wereHamster
Copy link
Author

I was hoping to hide the implementation detail and only expose the Scope type and the instances.

@meiersi
Copy link

meiersi commented Jul 24, 2012

OK. I was just reacting to the comments on the public methods, which described the implementation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment