Jeffrey Cross
Jeffrey Cross

コードボックス:処理中の例外処理

Codebox:センサーデータをGoogle Spreadsheetsに保存すると、Stairs氏はArduinoデバイスを接続していなかったときにスケッチが爆発することを発見しました。彼がその装置を掘り出し、それを差し込み、そしてスケッチを再開した時、それはうまくいった。

これは、処理、プログラミング、そして一般的な生活についての素晴らしいポイントを示しています。私たちは不完全な世界に住んでいます。素敵な小さなスケッチは、Arduinoが接続されていない状態で始められ、数字はゼロで割られ、人々はハサミで走ります。処理では、次のような条件が呼び出されます。 例外この記事では、どのように対処するか(または、より正式には、 ハンドル)それら。 (注:この記事はハサミで走るのを妨げるものではありません。)

それでは、まず最初に、Processingはどのようにして本当に問題が発生したのかを知らせますか?一般的には(何かがひどく間違っていない限り)、スケッチを始めて、そして次の図のような何かを見るでしょう:

メッセージ領域に赤のエラーメッセージがすべて表示されていることに注意してください。ここで、Processingが問題の原因について通知します。この場合、エラーは PortInUseException()これは、Googlingを起動すると、Processingで市松模様の評判が得られることがわかります。このメッセージは、エラーがどの行で発生したのかも示します。 投げた。さらに、問題の行はテキストエディタで黄色で強調表示されています。エラーが発生した場所に応じて、スケッチウィンドウは表示される場合と表示されない場合があります。たとえ表示されていても、ほぼ確実に期待通りの結果にはなりません。

このエラーを再現するには(またはそれと同じようなもの - 投稿の下部にある警告のセクションを参照してください!)、simple_port.pdeのテキストをProcessingに貼り付けます。すべてうまくいけば、スケッチは1秒に1回シリアルポートを読み取り、経過時間とポートから読み取った値を表示します。

もちろん、私たち全員がうまくいくことを望んでいるわけではありません(それがこの記事の要点です)ので、スケッチを実行するときにArduinoのプラグが抜かれていることを確認してください。前の図に似たものが見えるはずです。これで、対処するコードを追加する準備が整いました(または ハンドル、これは正式な用語です)切断されたデバイス。

Processing(およびそのProcessingがサブセットであるJava)の例外を処理するために、疑わしいコードを“ try-catch-finally”ブロックの中に配置します。処理はコードを実行しようとし、例外が投げられた場合、他のブロックに「キャッチ」されます。構文は次のようになります。

試してください{ 実行しようとしている疑わしいコード catch(ExceptionType1 e1){ // tryブロックでExceptionType1がスローされた場合に実行されるコード println(e1.getMessage()); catch(ExceptionType1 e2){ // tryブロックでExceptionType2がスローされた場合に実行されるコード println(e2.getMessage()); catch(ExceptionType3 e3){ // tryブロックでExceptionType3がスローされた場合に実行されるコード println(e3.getMessage()); ... } 最後に { //ここでコードを整理する ... }

例外については、Getting Started with Processingで説明されていないので、いくつかの一般的な質問に答えましょう。

  • どういう意味 疑わしいコード? 最初は、すべてのコードが疑わしいと思うかもしれませんが、例外処理は主に、ファイルの読み書き、ネットワークを介したデータの取得、デバイスとの通信(シリアルポートなど)など、いくつかの重要な状況で使用されます。実際、多くのライブラリでは、特定のメソッドをtry-catchブロックまたはコードをまったくコンパイルしないで囲む必要があります。たとえば、Googleスプレッドシートのコードからtryブロックを削除した場合、プログラムはコンパイルされません。図書館デザイナーはプログラマーを良い習慣にさせるためにこれを行います。
  • これらすべてのcatchステートメントは何ですか?コードはあらゆる点で問題を起こす可能性があるため、さまざまな可能性を処理できる必要があります。そのため、各catchステートメントは特定の種類のエラーに関連付けられています。その特定の種類のエラーが発生した場合は、対応するコードブロックが実行されます。たとえば、ファイルからデータを読み込もうとしているとします。ファイルが存在しない可能性があります。 FileNotFoundException 例外。または、ファイルが存在している可能性がありますが、ファイルを読んでいる間に何らかの理由で使用できなくなります。これは EOFException。あるいは、IOストリームでちょっと変わったことが起こって、それがひょうきんを投げかける IOException。これらの状況ごとにcatchブロックを作成できます。おそらく最もよい例えは、Getting Started本の64ページに記述されているif-then-elseブロックです。
  • catchの後の括弧内のものはどういう意味ですか?これらは関数への引数に似ています - 最初のトークンはブロックを起動させる例外のタイプを識別し、2番目は例外のデータとメソッドにアクセスすることを可能にする変数です。 (例外は、Processing内のすべてのものと同様に、オブジェクトです。)たとえば、次のような行があるとします。 catch(FileNotFoundException e)tryブロック内のコードが探しているファイルを見つけられなかった場合、そのブロックは実行されます。ブロックの中には、という変数があります。 e 何が悪かったのかについてもっと知るために使うことができます。たとえば、あなたはそれを使用することができます getMessage() エラーの詳細をメッセージ領域に出力する方法
  • catchステートメントの順序は重要ですか?はい。処理は、例外のクラスまたはスーパークラスに一致する最初のcatchブロックを起動します。オブジェクトは階層的であるため、いくつかの例外は他よりもフードチェーンの上位にあります。その結果、それらはほとんどすべてに一致します。 (最高ランクの例外クラスは 例外つまり、最も具体的な型の例外を最初に配置し、より一般的な例外を後で配置する必要があります。
  • 「ついに」とはどういう意味ですか?の 最後に ブロックはオプションであり、あなたがするコードを追加することができます 常に エラーが発生したかどうかにかかわらず、実行します。これは通常、クリーンアップコードに使用されます。たとえば、ファイルを開いた場合、finallyブロック内でそのファイルを閉じることができます。
  • キャッチブロックに正確なタイプのエラーがない場合はどうなりますか?簡単な答えはあなたのプログラムが爆破することです。これは、 未処理の例外、一般的にあなたが避けようとしているものです。すべての最後のキャッチとして、あなたは単に追加することができます catch(例外e) 最後のcatchブロックとして。これは最も一般的なタイプの例外オブジェクトなので、ほとんどのエラーをキャッチする必要があります。

うわー。十分な理論私たちのコードが爆発するのを防ぐという元々の問題に戻りましょう。 (それでも、私たちは表面を傷つけただけです。もっと詳しく知りたい場合は、レッスン:例外、Oracleからの素晴らしいチュートリアルをご覧ください。)

私たちのコードはライン上で爆発しているので port = new Serial(this、arduinoPort、9600)。これはtry-catchブロックを置くための非常に明白な場所です。このコードに実行させたいのは、この行にまったく例外がないかどうかをテストすること(私たちは本当に何を気にする必要はありません)、ある場合は「Plug in Arduino」メッセージを表示します。 Arduinoが接続されるとすぐに、カウンタとシリアルポートからの現在の値の表示を開始したいと思います。これが、コードの改訂版simple_port2.pdeです。

このコードを実行すると、次の図のようなものが見えるはずです。

それで、ここで何が起こっているの?あなたが最初に気付くのは、私が問題のある行を セットアップ() 方法とに ドロー() 方法。これにより、スケッチはArduinoが見つかったかどうかを繰り返しテストします。でテストをする セットアップ() スケッチが始まるとき、それは一度だけ起こることを意味するでしょう。次に、というフラグを作成しました。 ardinoOK - このフラグがfalseの場合、ポートを取得してエラーメッセージを表示します。フラグがtrueならば、ポートを読み、値を表示します。最後に、私は port = new Serial(this、arduinoPort、9600)。 try-catchブロック内の行コマンドが成功したら、次に設定します。 arduinoOK 本当です。例外が発生した場合は、 catch(例外e) ブロックして設定 arduinoOK 偽にする。このコードは内側にあるので ドロー()、それはこの論理を何度も繰り返します。ほら!

注意事項

私がずっと前に示唆したように、このプロジェクトのための例外処理は対処するのが少し難しいです。たとえば、Stairs(この投稿をコメントした読者)は、 ArrayIndexOutOfBoundsExeption。これは、コードが 文字列arduinoPort = Serial.list()[0]:デバイスがないことを示します。 「ハ、」私は、その例外についてテストするだけだと思いました。しかし、私が自分のMacでそれを走らせたとき、私はすでにリストにいくつかのデバイスを見つけたので、それはStairsが得ていた同じエラーで爆発することはなかった。次の表に示すように、Arduinoのプラグインは単に2つの新しい項目をリストに追加しました。

Arduinoがインストールされていません Arduinoインストール済み
ネイティブLIBバージョン= RXTX-2.1 =========================================安定図書館-7 Java libバージョン= RXTX-2.1-7 [0] "/dev/tty.Bluetooth-Modem" [1] "/dev/cu.Bluetooth-Modem" [2] "/dev/tty.Bluetooth-PDA-同期 "[3]" /dev/cu.Bluetooth-PDA-Sync " ネイティブLIBバージョン= RXTX-2.1 =========================================安定図書館-7 Java libバージョン= RXTX-2.1-7 [0] "/dev/tty.usbmodem1d11" [1] "/dev/cu.usbmodem1d11" [2] "/dev/tty.Bluetooth-Modem" [3] " /dev/cu.Bluetooth-Modem "[4]" /dev/tty.Bluetooth-PDA-Sync "[5]" /dev/cu.Bluetooth-PDA-Sync実験的:JNI_OnLoadが呼び出されました。

ちょっとGooglingはMacがデフォルトでカメラかブルートゥース装置のような新しい装置を拾うために走っているいくつかのプロセスを持っていることを示した。だから、私は階段はこれらのアイテムを持っていなかったPCの上になければならないと考えました。

しかし、私のコードはまだ膨れ上がっていましたが、別のエラーが発生しました。 gnu.io.PortInUseException。 「ハ!」私はしかし、私はちょうどそれをキャッチすることができます。しかし、これもうまくいきませんでした。グーグルを回って、私はOS Xにこの例外を捕まえることを厄介にする奇妙なバグがあるように思われること、そしてそれらを動かすためにシリアルライブラリの様々な部分を再インストールまたは削除しなければならないことを発見しました。だから、それはどちらもうまくいきませんでした。最後に、私は最も一般的なものをキャッチすることに決めました 例外 それを働かせるために。

それでは、スケッチの実行中にエラーを検出する方法についてもう少しやりたいと思いました。具体的には、Arduinoが接続されてスケッチが実行され始め、ストリームの途中でプラグを抜いた場合に対処したいと思いました。しかし、これを試したとき、私はオペレーティングシステムから来ているように思われるこのエラーメッセージを得ました:

それは食物連鎖でより高く扱われたので、エラーは例外としてProcessingに決して流れませんでした、それでスケッチはただ楽しいに沿ってハミングしました。うーん、私は思った。それで、ちょっとグーグルは私が計画したことをするのは非常に悪いことを明らかにしました、そしてそれはあらゆる種類の問題を引き起こすことができることを。だから、私は、Macには下流での問題を防ぐための保護手段が組み込まれていると思う。私は感謝すべきだと思います、しかしそれは私がこの例のためにぶつかった。

これらすべてが、プログラミングエラーを突き止めることは非常に多くの複雑さと相互依存性があるため、本当に、本当に困難である可能性があることを示しています。これがおそらく多くのプログラマーがMakersになる理由であると思います。 6ヵ月が永遠に続くことができる職業では、あなたがギアとレバーから造る機械がアリストテレスにおそらく理解可能であることを知っているのは満足です。率直に言って、世界がそれほどスムーズに動いているのは素晴らしいことです。

例外処理担当者はいたるところにありがとうございます。

メーカーの小屋で:


Processing入門Processing、コードを使用して図面、アニメーション、インタラクティブグラフィックを作成するための簡単な言語であるProcessingを使用して、コンピュータプログラミングを簡単に学ぶことができます。プログラミングコースは通常理論から始まりますが、この本では創造的で楽しいプロジェクトに飛び込むことができます。基本的なプログラミングを学びたい人には理想的で、プログラミングのスキルを持っている人のためのグラフィックスの簡単な紹介としても役立ちます。

シェア

コメントを残します