Blocs try transactionnels dans ValueScript
Les exceptions sont difficiles à corriger. Un problème particulièrement délicat qu'il est facile d'ignorer est la possibilité d'une évaluation partielle à l'intérieur trydes blocs.
Considérez le programme JavaScript suivant :
let a = new SmallQueue(["item1"]);
let b = new SmallQueue(["item2", "item3", "item4"]);
try {
const item = a.pop();
b.push(item);
} catch (e) {
console.error("Failed to move item from a to b", e);
}
console.log({ a, b });
{
a: [],
b: ["item2", "item3", "item4", "item1"],
}
{
a: [],
b: ["item2", "item3", "item4"],
}
let a = new SmallQueue(["item1"]);
let b = new SmallQueue(["item2", "item3", "item4"]);
try {
if (b.isFull()) {
throw new Error("b is full");
}
const item = a.pop();
b.push(item);
} catch (e) {
console.error("Failed to move item from a to b", e);
}
console.log({ a, b });
Une autre option consiste à enregistrer une copie des variables susceptibles de changer et à les restaurer sur catch:
let a = new SmallQueue(["item1"]);
let b = new SmallQueue(["item2", "item3", "item4"]);
const aCopy = a.copy();
const bCopy = b.copy();
try {
const item = a.pop();
b.push(item);
} catch (e) {
a = aCopy;
b = bCopy;
console.error("Failed to move item from a to b", e);
}
console.log({ a, b });
- Vous ne le ferez peut-être pas parce que c'est verbeux et inutilement défensif
- Il nécessite une
copyopération à définir - Si l'
copyopération existe, elle pourrait ne pas être efficace - Si
a.popa des effets secondaires, ces effets secondaires ne seront pas annulés
let a = new SmallQueue(["item1"]);
let b = new SmallQueue(["item2", "item3", "item4"]);
let item;
try {
item = a.pop();
} catch (e) {
console.error("Failed to move item from a to b", e);
console.log({ a, b });
return;
}
try {
b.push(item);
} catch (e) {
a.unPop(item);
console.error("Failed to move item from a to b", e);
}
console.log({ a, b });
- Extrêmement verbeux
a.unPop(item)nous oblige à comprendre que cette opération est nécessaire en casb.push(item)d'échec, ce qui est encore facile à manquer
Dans ValueScript, tryles blocs sont transactionnels : soit ils s'exécutent jusqu'à la fin, soit ils sont annulés.
Notre programme original fait ce que nous voulions sans aucune modification :
let a = new SmallQueue(["item1"]);
let b = new SmallQueue(["item2", "item3", "item4"]);
try {
const item = a.pop();
b.push(item);
} catch (e) {
console.error("Failed to move item from a to b", e);
}
console.log({ a, b });
{
a: ["item1"],
b: ["item2", "item3", "item4"],
}
- "Vous ne le ferez peut-être pas"
- Le compilateur ValueScript insère automatiquement les instructions - "Nécessite
copyune opération"
- ValueScript utilise la sémantique de la valeur, il utilise simplementaCopy = a, et cela équivaut à copier - "
copypourrait ne pas être efficace"
- ValueScript utilise la copie sur écriture jusqu'au bout, c'est assez efficace - "Les effets secondaires de
a.popne seront pas annulés"
- ValueScript n'a pas d'effets secondaires
* certaines fonctions étrangères impressionnantes pourraient inclure des opérations de retour et celles-ci seraient automatiquement appelées
ValueScript est un dialecte de TypeScript avec une sémantique de valeur. Il dispose d'un terrain de jeu en ligne comprenant une démonstration du programme de cet article , et il est open source .
![Qu'est-ce qu'une liste liée, de toute façon? [Partie 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































