3

testexc.sml という名前のファイルに次の SML プログラムがあります。

structure TestExc : sig
               val main : (string * string list -> int)
               end =
  struct

  exception OhNoes;

     fun main(prog_name, args) = (
       raise OhNoes
     )

end

次のように smlnj-110.74 でビルドします。

ml-build sources.cm TestExc.main testimg

sources.cm に含まれる場所:

Group is
  csx.sml

次のようにプログラムを呼び出します (Mac OS 10.8 の場合):

sml @SMLload testimg.x86-darwin

プログラムを呼び出したときに何かが表示されることを期待していますが、返されるのはリターン コード 1 だけです。

$ sml @SMLload testimg.x86-darwin
$ echo $?
1

何を与える?この未処理の例外で SML がサイレントに失敗するのはなぜですか? この動作は正常ですか?発生したエラーを出力するメインに配置できる汎用ハンドラーはありますか? 例外 OhNoes を一致させることができることはわかっていますが、私が知らないかもしれない例外を含む大規模なプログラムについてはどうでしょうか?

4

1 に答える 1

2

答えは、例外を処理し、それを e と呼び、システムで利用可能ないくつかの関数を使用してデータを出力することです。

$ sml
Standard ML of New Jersey v110.74 [built: Tue Jan 31 16:23:10 2012]
- exnName;
val it = fn : exn -> string
- exnMessage;
val it = fn : exn -> string
-

これで、main() にジェネリック ハンドラーを追加して、変更したプログラムができました。

structure TestExc : sig
               val main : (string * string list -> int)
               end =
  struct

  exception OhNoes;
  open List;

     fun exnToString(e) =
        List.foldr (op ^) "" ["[",
                              exnName e,
                              " ",
                              exnMessage e,
                              "]"]

     fun main(prog_name, args) = (
       raise OhNoes
     )
     handle e => (
       print("Grasshopper disassemble: " ^ exnToString(e));
       42)

end

メッセージを生成するためにリストを使用したので、このプログラムをビルドするには、sources.cm の基本ライブラリへの参照が必要です。

Group is
  $/basis.cm
  sources.cm

これを実行すると、次のようになります。

$ sml @SMLload testimg.x86-darwin
Grasshopper disassemble: [OhNoes OhNoes (more info unavailable: ExnInfoHook not initialized)]
$ echo $?
42

ExnInfoHook が何かはわかりませんが、少なくとも OhNoes は表示されます。残念なことに、SML コンパイラーは、コンパイルされたプログラムで未処理の例外があったときに何かを出力するための基本的なハンドラーを追加しませんでした。ml-build がそのタスクを担当すると思います。

于 2013-12-13T21:40:52.033 に答える