Created
October 2, 2015 04:34
-
-
Save joshkunz/665b15e118caf1b3d65d to your computer and use it in GitHub Desktop.
A python implementation of the sealer/unsealer pattern from "E in a Walnut"
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Returns two classes, a "Sealer", and an "Unsealer". | |
# Lets call the Sealer "s" and the Unsealer "u". | |
# For any pair of s and u returned from makeBrandPair, s.seal(value) | |
# (where "value" can be any python object) returns a boxed version of | |
# value that cannot be extracted unless you have a reference to the | |
# unsealer u (not 100% sure on this, but it seems to be true). | |
# When you call u.unseal(box), the value originally sealed into the | |
# box is returned. A separate call to makeBrandPair will return | |
# a different sealer/unsealer pair that only work with eachother. | |
def makeBrandPair(): | |
shared = [None] | |
def makeSealedBox(obj): | |
# This class holds a reference to the stored value | |
class Box(object): | |
@classmethod | |
def unbox(kls): | |
shared[0] = obj | |
return Box() | |
class Sealer(object): | |
@classmethod | |
def seal(kls, obj): | |
return makeSealedBox(obj) | |
class Unsealer(object): | |
@classmethod | |
def unseal(kls, box): | |
# Make sure we're not accesing a value unboxed before | |
shared[0] = None | |
# Unbox our value | |
box.unbox() | |
# Make sure the box has a value | |
if shared[0] is None: raise Exception("invalid box") | |
# Get the value we just shared | |
contents = shared[0] | |
# Kill the shared value | |
shared[0] = None | |
# return a reference to the shared value | |
return contents | |
return Sealer, Unsealer | |
s, u = makeBrandPair() | |
box = s.seal("Hello World") | |
print u.unseal(box) | |
s2, u2 = makeBrandPair() | |
print "Should throw exception: u2.unseal(box)" | |
print u2.unseal(box) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment