This repository has been archived by the owner on Mar 29, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 19
/
the_locked_box.js
67 lines (54 loc) · 1.63 KB
/
the_locked_box.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
/*
2 - The Locked Box (15/1/2020)
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 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.
*/
"use strict";
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) {
const boxWasInitiallyLocked = box.locked;
if (boxWasInitiallyLocked) {
box.unlock();
}
try {
return body();
}
finally {
if (boxWasInitiallyLocked) {
box.lock();
}
}
}
withBoxUnlocked(function() {
box.content.push("gold piece");
});
try {
withBoxUnlocked(function() {
throw new Error("Pirates on the horizon! Abort!");
});
} catch (e) {
console.log("Error raised: " + e);
}
console.log(box.locked);
// → true