失敗は怖いかもしれません。しかしこれは、プログラミングの重要な部分です。 失敗により、デバッグ方法を学習したり、プログラムの限界を見つけたり、何をしてはいけないかをすぐに確認したりすることができます。
失敗しても大丈夫
Verse における「失敗」は特定の意味を持ちます。 必ずしも、「何かがうまくいかなかったこと」を指すわけではありません。 Verse では、プログラムの動作を制御する 1 つの方法となります。
レッスン 4 で、「はい」または「いいえ」で答える質問をするコードを作成できることを学習した際を思い出してください。
var Tired: logic = false
var WhatToWatch: string = “nothing”
if (Tired?):
set WhatToWatch = “your eyelids”
else:
set WhatToWatch = “cartoons”
Print(“You should watch {WhatToWatch}”)
質問を行うコードは失敗する可能性がある式として記述されています。 上の例では、Tired? は失敗する可能性がある式です。
失敗する可能性がある式は、プログラムが完全に動作しなくなる可能性があるエラーを回避するために使用されます。 たとえば、ゼロを除算するのは不可能であることはご存じだと思います。 コードでこれを実行しようとすると、クラッシュする可能性があります。 ただし、次の Verse コードは問題なく実行されます。
if (5/0):
Print("Whoa!")
else:
Print("You can't do that!")
Verse でこのような類のエラーを回避するには、失敗する可能性がある式を失敗コンテキストで記述する必要があります。 失敗コンテキストを使用すると、失敗する可能性がある式において安全な形で失敗できるようになります。 上の例では、5/0 が失敗する可能性がある式、if() が失敗コンテキストとなっています。 これらの Verse の両方の概念についての詳細は、以下をお読みください。
失敗する可能性がある式
Verse で失敗する可能性がある式を記述する方法はたくさんあります。 式が「はい」か「いいえ」で答える質問をしている場合、失敗する可能性が多分にあります。
失敗する可能性がある式で尋ねられる質問には、次のようなものがあります。
これら 2 つの変数は互いに大きいか、小さいか、または等しいのか?
この変数は
trueに設定されているか?この変数には値が設定されているか?
この式はエラーを引き起こすか?
これらの質問のいずれかの答えが「はい」であれば、式は成功します。 答えが「いいえ」の場合、式は失敗します。 成功または失敗の後に何が起こるかは、コードの記述方法によって異なります。
比較式
< (より小さい)、 > (より大きい)、または <> (等しくない) などの比較演算子を使用する 比較式 は失敗する可能性があります。 次の例のうち、5 < 4 は失敗する可能性がある式です。
if (5 < 4):
Print(“This will never print.”)
5 < 4 という式は、「5 は 4 より小さいか?」と尋ねていることになります。 答えは いいえ です。式は失敗し、コード ブロック (if 式の下にインデントされている) は実行 されません。
次の例と、失敗する可能性がある式 MousetrapsSet <> MiceCaught を見てみましょう。 これは、「MousetrapsSet と MiceCaught の値は等しくないか?」と尋ねています。
MousetrapsSet := 3
MiceCaught := 0
if (MousetrapsSet<>MiceCaught):
Print(“Need more cheese!”)
今回は、MousetrapsSet が 3 で MiceCaught が 0 であるため、質問に対する答えは「はい」となり、式は成功し、コード ブロックは実行されます。
判定式
演算子 and、or、not を使用する判定式は失敗する可能性があります。 次の例の失敗する可能性がある式 MousetrapsForSale > 0 and Coins >= MousetrapCost は、MousetrapsForSale は 5 (0 より大きい)、Coins は 30、 MousetrapCost は 20 (30 は 20 より大きい) であるため、成功します。 どちらの式も単独で成功するため、式全体が成功します。
MousetrapsForSale := 5
MousetrapCost := 20
Coins := 30
if (MousetrapsForSale > 0 and Coins >= MousetrapCost):
Print(“You can buy mouse traps.”)
クエリ式
クエリ式も失敗する可能性があります。 特定の値の確認に ? 演算子を使用して、クエリ式は、logic の値が true であるかどうかを確認します。 次の例では、MousetrapStoreOpen? は失敗する可能性がある式ですが、MousetrapStoreOpen が false であることから失敗します。
var MousetrapStoreOpen : logic = false
if (MousetrapStoreOpen?):
Print(“Come on in!”)
失敗コンテキスト
上記のすべてのコード例では、if 式は、() 内に含まれる失敗する可能性がある式の失敗コンテキストでした。 失敗コンテキストは、失敗した場合に何が起こるかを決定します。したがって、失敗する可能性がある式を安全な形で失敗させることができます。
前のレッスンで、if にある式が失敗すると、if コード ブロック内のコードが実行されないことがわかりました。
if は失敗コンテキストを作成するため、コード ブロックに失敗する可能性がある式を好きなだけ入れることができます。 これらの式のいずれかが失敗した場合、コード ブロック内の以前の式は元に戻されるか、ロールバックされます。
() を使用せずに if 式を作成する別の方法もあります。 多くの式を記述する必要がある場合に便利です。 以下に例を示します。
MousetrapsSet:int = 5
var MiceCaught:int = 0
var BreakTime:logic = false
if:
MousetrapsSet > 0
set BreakTime = true
MiceCaught > 0
if (BreakTime?):
失敗コンテキスト内のすべての式を失敗できる状態にする必要はありませんが、少なくとも 1 つはそうしてください。 上の例では、set BreakTime = true は失敗しませんが、他の式は失敗します。
上記のコードでは、if の下にあるインデントされたすべての式が失敗コンテキスト内にあります。 3 つの式すべてが実行されます。
MousetrapsSet > 0は成功します。式
set BreakTime = trueが実行されます。 失敗しないため、失敗チェックはありません。ただし、
MiceCaught > 0は失敗します。
失敗したため、set BreakTime = true を含む if コード ブロック内のすべての式がロールバックされます。 したがって、コードがまったく実行されなかったかのような状態になります。 このコードを実行すると、「Catch some mice! (ネズミを捕まえてください!)」というメッセージが表示されます。
プログラミングをしていると、多くのコードは他のコードが正常に実行された場合にのみ動作することがわかります。 これが、失敗コンテキストが非常に役立つもう 1 つの理由です。 依存コードを失敗コンテキストにグループ化すると、いくつかの一般的なバグを回避できます。 レッスン 4 で映画に行くかどうかを決めるために使用したコードを思い出してください。 友達と一緒に行くことが決まったら、チケット、飲み物、軽食を友達に買ってもらう必要があります。
var Drinks:int = 4
var Snacks:int = 4
var Tickets:int = 3
var FriendsAvailable:int = 4
if:
Drinks >= FriendsAvailable
set Drinks -= FriendsAvailable
Snacks >= FriendsAvailable
set Snacks -= FriendsAvailable
演算子 -= は、減算 と 代入 を組み合わせるためのショートカットです。 上の例では、set Tickets -= FriendsAvailable は set Tickets = Tickets - FriendsAvailable と同じです。 これは、加算 (+=)、乗算 (*=)、除算 (/=) でも動作します。
参加可能な友人のために十分な飲み物と軽食を用意しましたが、チケットは足りません。 つまり、あなたとあなたの友達全員が映画を見られません。 このような状況に対処するコードを作成することもできますが、飲み物や軽食を配りたくはないと思います。
幸いなことに、式 Tickets >= FriendsAvailable を実行すると失敗し、if ブロック内のすべてのコードがロールバックされます。 つまり、Drinks 変数と Snacks 変数が両方とも値 4 を持つ状態に戻ります。
まとめ
Verse では、失敗 はプログラムを制御する方法の 1 つです。
失敗する可能性がある式は成功することも失敗することもあり、それは失敗コンテキスト内で記述する必要があります。 成功または失敗の後に何が起こるかは、コードの記述方法によって異なります。
失敗コンテキストを使用すると、失敗する可能性がある式において安全な形で失敗できるようになります。 失敗コンテキスト内で失敗すると、そのコンテキスト内のすべてのコードは、あたかも実行されなかったかのようにロールバックされます。