トラック
/
Factor
Factor
/
演習
/
工場のフェイルセーフ
工場のフェイルセーフ

工場のフェイルセーフ

学習演習

はじめに

Factorのエラーシステムは、3つの要素からできています。エラーを知らせるthrow、エラーを処理するrecover、そして独自のエラーを定義するERROR:です。

throw

throw(kernelにあります)はエラーを発生させます。引数には文字列・数値・タプルなど、どんな値でも渡すことができ、その値が後から確認できるエラーになります。

! DOCTEST: SKIP
"file not found" throw

throwは戻りません。現在のワードの残りの部分はスキップされます。

recover

recover(continuationsにあります)は、Factorのtry/catchです。tryクォーテーションとrecoveryクォーテーションを受け取ります。

recover ( try recovery -- )

tryがthrowせずに終われば、recoveryは無視されます。tryがthrowすると、エラーがスタックに積まれ、recoveryが実行されます。

[ "boom" throw ] [ drop "caught" ] recover .
! => "caught"

[ "ok" ] [ drop "never runs" ] recover .
! => "ok"

kernelのwhenは自然な相棒です。スタックの一番上が真と評価されるときだけ、クォーテーションを実行します。

: check-positive ( n -- )
    0 < [ "negative!" throw ] when ;

ERROR:

ERROR:はタプルクラスと、新しいインスタンスを生成してthrowするワードを定義します。

! DOCTEST: SKIP
ERROR: not-found path ;

"/missing" not-found
! throws T{ not-found { path "/missing" } }

スロットを持たないエラーは、単にERROR: name ;と書くだけです。nameを呼び出すと、空のインスタンスがthrowされます。ERROR:で定義したタプルには、クラスの述語name?が付いており、捕まえたエラーがその型のものかどうかを確かめられます。

スロットの値を取り出す

捕まえたエラーはただのタプルなので、ERROR:の各スロットには、ほかのタプルと同じ、自動生成されたslot>>リーダーが付いています。

! DOCTEST: SKIP
{
    T{ not-found { path "/a" } }
    T{ not-found { path "/b" } }
}
[ path>> ] map .   ! => { "/a" "/b" }

説明

新聞工場の新しい品質管理責任者であるElenaは、製造室を監視する小さなソフトウェアを書いてほしいと頼んできました。

1. 独自のエラーを定義する

ERROR:パースワードを使って、エラータプルクラスmachine-errorを定義します。スロットは必要ありません。

machine-error   ! throws a fresh machine-error

2. 湿度をチェックする

check-humidityを定義します。これはスタックから湿度の測定値を取り出し、その値が厳密に70より大きいとき、文字列"humidity too high"をthrowします。それ以外の場合は何も返しません。

50 check-humidity   ! returns nothing
80 check-humidity   ! throws "humidity too high"

3. 温度をチェックする

check-temperatureを定義します。これは温度の測定値を取り出し、その値が厳密に500より大きいとき、文字列"temperature too high"をthrowします。それ以外の場合は何も返しません。

400 check-temperature   ! returns nothing
600 check-temperature   ! throws "temperature too high"

4. 機械を監視する

monitorを定義し、スタックから湿度と温度を取り出して、両方のチェックを実行します。どちらかのチェックがthrowしたら、代わりにmonitorが新しいmachine-errorをthrowします。両方とも通れば、monitorは何も返しません。

50 400 monitor   ! returns nothing
80 400 monitor   ! throws a machine-error
50 600 monitor   ! throws a machine-error

5. 測定値のバッチを監視する

monitor-batchを定義し、{ humidity temperature }の測定値の配列を受け取って、そのうち何件が失敗するか(つまり、何件がmonitorにthrowさせるか)を返します。

{ { 50 400 } { 80 400 } { 50 600 } { 60 200 } } monitor-batch .
! => 2
GitHubで編集する リンクは新しいウィンドウまたはタブで開きます
Factor Exercism

工場のフェイルセーフを始める準備はできましたか?

Exercismに登録すれば、47個のコンセプト163個の演習、そして本物の人間によるメンタリングとともに、Factorを学んでマスターできます。すべて無料です。