Skip to content

Instantly share code, notes, and snippets.

@jonurry
Last active March 15, 2018 16:40
Show Gist options
  • Save jonurry/ad27dc489fea15cf0642ef470443e458 to your computer and use it in GitHub Desktop.
Save jonurry/ad27dc489fea15cf0642ef470443e458 to your computer and use it in GitHub Desktop.
8.2 The Locked Box (Eloquent JavaScript Solutions)
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
@jonurry
Copy link
Author

jonurry commented Mar 15, 2018

8.2 The Locked Box

Consider the following (rather contrived) object:

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;
  }
};

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.

@jonurry
Copy link
Author

jonurry commented Mar 15, 2018

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