最初の小さなCLIアプリ
Docsの目次 · 前:準備と最初の実行 · 次:コードを書きながら学ぶ
入力した金額が1,000円以内かを判定するCLIアプリを作ります。Nagiの公開compilerをインストールし、Rust/CargoとCのビルド環境を用意してください。準備がまだならセットアップを先に進めます。
この例は1行の入力だけを扱い、結果を画面に表示します。ファイルやDBには保存しません。データ保存を追加するときはSQLiteの現在のAPIと制約を確認してください。
このページの目次
1. 作業フォルダーとファイルを作る
ターミナルで作業場所を選び、次のコマンドを実行します。nagi-budgetという新しいフォルダーを作り、その中を作業場所にします。
mkdir nagi-budget
cd nagi-budget
このフォルダーにfirst_app.nagiを作り、次のコードを保存してください。同じコードはリポジトリの実行例にあります。
def within_budget(amount_text: view[str], limit: i64) -> Result[bool, Error]:
amount = try parse_i64(amount_text)
if amount < 0:
return error("amount must be non-negative")
return ok(amount <= limit)
def main() -> Result[unit, Error]:
print("Enter a whole-number amount:")
text = try read_line()
fits = try within_budget(view(text), 1000)
if fits:
print("within budget")
else:
print("over budget")
return ok(print("done"))
mkdirとcdは成功すると何も表示しません。エディターで保存したファイルがnagi-budget/first_app.nagiにあることを確認してください。フォルダーが既にある場合は、mkdirを繰り返さずそのフォルダーへ移動します。
within_budgetは入力文字列を整数に変換します。view[str]は文字列を読むための借用で、parse_i64の失敗はResult[i64, Error]として返ります。tryは失敗をこの関数の呼び出し元へ伝えます。負の金額を拒否した後、okで判定結果を返します。mainでもtryを使うため、mainの戻り値はResultです。
初出の用語は、viewとownershipとResult・try・matchで詳しく確認できます。unitは値を返さない処理の型で、ここではprintの結果をok(...)に入れています。
2. 検査して動かす
同じ作業フォルダーで、compilerの版とソースを確認します。
nagic --version
nagic check first_app.nagi
対象compilerがNagi 0.1.11なら、版表示はnagic 0.1.11です。checkが成功すると終了コードは0で、Nagiの構文・型・所有権について診断がありません。checkはRust/Cargoのビルドを行いません。
成功時はcheckedに続いて確認したファイルのpathが表示されます。失敗した場合はsourceの行を確認し、nagic --versionで0.1.11以降を使っていること、first_app.nagiを作業フォルダーに保存したことを確かめてください。
LinuxとmacOSでは、標準入力から金額を渡して実行できます。
printf '700\n' | nagic run first_app.nagi
PowerShellでは同じ確認を次のように実行できます。
"700" | nagic run .\first_app.nagi
アプリの標準出力は次のとおりです。compilerの進捗やエラーは別の診断として表示されることがあります。
Enter a whole-number amount:
within budget
done
runはRust/Cargoによるアプリのbuildと実行を行います。そのためcheckが通っても、C compilerやlinkerがない、依存を取得できない、といった理由で実行前に失敗することがあります。準備はセットアップ、build診断は検査とビルドを確認してください。
3. 境界値を試して間違いを直す
実際に間違いを観測するため、within_budgetのreturn ok(amount <= limit)を一時的にreturn ok(amount < limit)へ変更して保存します。作業フォルダーからcheckし、上限と等しい1000を入力してください。
nagic check first_app.nagi
printf '1000\n' | nagic run first_app.nagi
nagic check .\first_app.nagi
"1000" | nagic run .\first_app.nagi
この状態では1000の判定行がover budgetになります。上限と等しい額も受け入れるため、比較をamount <= limitへ戻して保存します。nagic check first_app.nagiをもう一度実行し、次の3入力で修正を確認してください。
| 入力 | 期待する出力 | 確かめること |
|---|---|---|
700 |
within budget |
上限より小さい値 |
1000 |
within budget |
上限と等しい値 |
1001 |
over budget |
上限より大きい値 |
1000でover budgetになったら、比較をamount <= limitへ直します。nagic check first_app.nagiを再実行し、3入力の結果をもう一度確かめてください。
LinuxとmacOSでは次の3コマンドを実行します。PowerShellでは右の3行を使います。
printf '%s\n' '700' | nagic run first_app.nagi
printf '%s\n' '1000' | nagic run first_app.nagi
printf '%s\n' '1001' | nagic run first_app.nagi
"700" | nagic run .\first_app.nagi
"1000" | nagic run .\first_app.nagi
"1001" | nagic run .\first_app.nagi
各コマンドはプロンプトの後に表の判定、doneの順で表示します。abcは数値変換の失敗、-1はアプリが作った失敗として終了コード1になります。次の表は、compiler診断ではなく、起動したアプリが実行時に表示するエラーです。Nagi 0.1.11での表示は次のとおりです。
| 入力 | 実行時エラー出力 | exit code |
|---|---|---|
abc |
Invalid: invalid digit found in string |
1 |
-1 |
Invalid: amount must be non-negative |
1 |
Linux/macOSではprintf '%s\n' 'abc'またはprintf '%s\n' '-1'を、PowerShellでは"abc"または"-1"を同じようにpipeして確認できます。実行時エラーが表示されたらResultの伝播と回復を確認してください。アプリが起動する前にcompilerやCargoの診断が出た場合は、前節のbuild準備と検査とビルドを確認します。
負数はアプリが作ったError、abcはparse_i64が返すErrorになります。どちらもtryを通ってmainへ伝わります。失敗をその場で別の値に置き換える方法はResultとエラー処理を参照してください。
開発中のNagiには組み込みの単体テストフレームワークはありません。ここでは小さな入力表を手動で実行し、期待結果と比較します。compiler本体を変更するときの自動回帰テストは貢献ガイドとcompiler test guideを参照してください。
4. 次に広げる
関数、List、class、ループ、enum、nullable、Result、matchの使い分けは言語ガイドと言語機能索引へ。入力を複数ファイルに分けるときはimportとmodule、別の値を安全に受け渡すときはownershipとborrow、Rustライブラリを呼ぶときはRust連携を読みます。