Last active
March 15, 2018 16:40
-
-
Save jonurry/ad27dc489fea15cf0642ef470443e458 to your computer and use it in GitHub Desktop.
8.2 The Locked Box (Eloquent JavaScript Solutions)
This file contains hidden or 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
const box = { | |
locked: true, | |
unlock() { this.locked = false; }, | |
lock() { this.locked = true; }, | |
_content: [], | |
get content() { | |
if (this.locked) throw new Error("Locked!"); | |
return this._content; | |
} | |
}; | |
function withBoxUnlocked(body) { | |
let boxLockedOnEntry = box.locked; | |
if (boxLockedOnEntry) { | |
box.unlock(); | |
} | |
try { | |
body(); | |
} finally { | |
if (boxLockedOnEntry) { | |
box.lock(); | |
} | |
} | |
} | |
// try with the box locked | |
withBoxUnlocked(function() { | |
box.content.push("gold piece"); | |
}); | |
// check that box is still locked after adding gold piece | |
console.log(box.locked); | |
// → true | |
// try with locked box that raises error once opened | |
try { | |
withBoxUnlocked(function() { | |
throw new Error("Pirates on the horizon! Abort!"); | |
}); | |
} catch (e) { | |
console.log("Error raised:", e); | |
} | |
// check that box is still locked after error | |
console.log(box.locked); | |
// → true | |
// unlock the box | |
box.unlock(); | |
// add silver piece to box that is unlocked | |
withBoxUnlocked(function() { | |
box.content.push("silver piece"); | |
}); | |
// check that box is still unlocked after adding silver piece | |
console.log(box.locked); | |
// → flase | |
// raise error on unlocked box | |
try { | |
withBoxUnlocked(function() { | |
throw new Error("Pirates on the horizon! Abort!"); | |
}); | |
} catch (e) { | |
console.log("Error raised:", e); | |
} | |
// check that box is still unlocked after error | |
console.log(box.locked); | |
// → false |
Hints
This exercise calls for a finally
block. Your function should first unlock the box and then call the argument function from inside a try
body. The finally
block after it should lock the box again.
To make sure we don’t lock the box when it wasn’t already locked, check its lock at the start of the function and unlock and lock it only when it started out locked.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
8.2 The Locked Box
Consider the following (rather contrived) object:
It is a box with a lock. There is an array in the box, but you can get at it only when the box is unlocked. Directly accessing the private
_content
property is forbidden.Write a function called
withBoxUnlocked
that takes a function value as the argument, unlocks the box, runs the function, and then ensures that the box is locked again before returning, regardless of whether the argument function returned normally or threw an exception.For extra points, make sure that if you call
withBoxUnlocked
when the box is already unlocked, the box stays unlocked.