C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[16]: 契約プログラミングと例外処理の使い分けについて


(過去ログ 41 を表示中)

[トピック内 33 記事 (1 - 20 表示)]  << 0 | 1 >>

■21060 / inTopicNo.1)  契約プログラミングと例外処理の使い分けについて
  
□投稿者/ ネタ好き (483回)-(2008/06/24(Tue) 10:58:28)

分類:[雑談] 

ネタ元はhttp://blogs.wankuma.com/episteme/archive/2008/06/23/145011.aspx(επιστημηさんの記事)です。そこで気になったのが契約プログラミングで使用するassertと例外処理の使い分けについてです。
皆様はどのように契約プログラミングを実施しておりますか?
または、契約プログラミングと例外処理についてはどう使い分けるべきだと思いますか?
ご意見をお待ちしております。
引用返信 編集キー/
■21062 / inTopicNo.2)  Re[1]: 契約プログラミングと例外処理の使い分けについて
□投稿者/ επιστημη (1114回)-(2008/06/24(Tue) 11:44:05)
επιστημη さんの Web サイト
> または、契約プログラミングと例外処理についてはどう使い分けるべきだと思いますか?

契約プログラミングでの事前条件/事後条件は関数の定義域/値域が正しいかを確認するもの。
関数の定義域/値域が範囲外てーことは"バグ"です。
例外飛ばすのは"救済したい/できる"という意図の表れと考えます。

で、僕は「バグは救済しちゃならん。その旨を速やかに報告し落ちるべし」をキホンとしてます。
なので事前条件/事後条件はassertを使い、ひっかかったら素直にコケてもらいます。

例外はあるでしょうよ。でもそれは"特例"としたい。
事前条件/事後条件にひっかかるのを
"あってはならん" とするか
"万が一にも(バグじゃなく)起こりうる" とするか、じゃないかしら。
僕はキホン前者です。てか"あってはならん"ことの検証にassertを用います。


引用返信 編集キー/
■21067 / inTopicNo.3)  Re[2]: 契約プログラミングと例外処理の使い分けについて
□投稿者/ れい (675回)-(2008/06/24(Tue) 13:23:33)
No21062 (επιστημη さん) に返信
>>または、契約プログラミングと例外処理についてはどう使い分けるべきだと思いますか?
>
> 契約プログラミングでの事前条件/事後条件は関数の定義域/値域が正しいかを確認するもの。
> 関数の定義域/値域が範囲外てーことは"バグ"です。
> 例外飛ばすのは"救済したい/できる"という意図の表れと考えます。
>
> で、僕は「バグは救済しちゃならん。その旨を速やかに報告し落ちるべし」をキホンとしてます。
> なので事前条件/事後条件はassertを使い、ひっかかったら素直にコケてもらいます。
>
> 例外はあるでしょうよ。でもそれは"特例"としたい。
> 事前条件/事後条件にひっかかるのを
> "あってはならん" とするか
> "万が一にも(バグじゃなく)起こりうる" とするか、じゃないかしら。
> 僕はキホン前者です。てか"あってはならん"ことの検証にassertを用います。

Release環境ではassertは消えちゃいますが、
それはどう解釈したらよいのでしょう?

Releaseはバグ無しが前提なのでassert無しでもOKということかしら?
引用返信 編集キー/
■21069 / inTopicNo.4)  Re[3]: 契約プログラミングと例外処理の使い分けについて
□投稿者/ 凪瀬 (58回)-(2008/06/24(Tue) 13:33:01)
凪瀬 さんの Web サイト
基本的な考え方は「契約不履行 = バグ」 ですね。
そして、バグはできるだけ速やかにその存在を消さねばならないので、発生したらデバッグに必要な情報を提供した上で落とすという考え方になります。
リリース時までには完全に取り除くことが前提となりますけども。

Javaの場合はassertを使ってチェックすることもできますが、共通ライブラリなどでは入力値をチェックして適切なRuntimeExceptionをthrowするのが通例です。
RuntimeExceptionと違い、assertはoff時にコストがかからないのがメリットですが、よほど繰り返しの大きい場所でない限り、大したコストにはなりませんから引数異常のIllegalArgumentExceptionをthrowする作りにすることが多いかな。
引用返信 編集キー/
■21070 / inTopicNo.5)  Re[3]: 契約プログラミングと例外処理の使い分けについて
□投稿者/ επιστημη (1115回)-(2008/06/24(Tue) 13:36:14)
επιστημη さんの Web サイト
> Release環境ではassertは消えちゃいますが、
> それはどう解釈したらよいのでしょう?
>
> Releaseはバグ無しが前提なのでassert無しでもOKということかしら?

「Release環境ではassertが消える」ぢゃなくてー
「Release環境では-DNDEBUGするからassertが消える」なので
「-DNDEBUGせずにRelease-buildすればassertは消えない」のです C/C++のばやい♪

それはまぁいいとして

えと、確かに契約プログラミング自体、Release時には消すように考えてるみたいです。
事前条件/事後条件にひっかかるのを"あってはならん"こととしてるならそれでいいのかもです。

不安は残りますよね。鼻から悪魔でてきちゃいますよね。

引用返信 編集キー/
■21071 / inTopicNo.6)  Re[2]: 契約プログラミングと例外処理の使い分けについて
□投稿者/ じゅで (60回)-(2008/06/24(Tue) 13:40:16)
本当の例外は、落ちるべきだと思います。

ただ、Debug.Assertを使用しての、中断は行っていません。
基本的に、どのような例外であれ、呼出元には、こういう理由でエラーにしたからと
伝えるべきだと考えているからなのですが、それがどうしてかというと、
例外が発生した場合、例外の内容でどのように振舞うかは、対象となるオブジェクトを
使う側が決めるからという理由です。

ですので、パラメータチェックでおちたならパラメータチェックでおちたよと
Exceptionをあげてあげます。

そのExceptionの内容にあわせて、XMLコメントもできる限り記載しております。

その上で、その例外をどうしたいのかは、使う側が落としたいなら、
「例外を呼出元に伝搬して下さいね」という形にしています。

> 僕はキホン前者です。てか"あってはならん"ことの検証にassertを用います。

たぶん、私がやっている事は、assertを使わないで、自前でチェックをしておき、
処理を中断させるか、Exceptionを飛ばしているだけの違いだと考えております。

# もしかして、根本的に勘違いをしていたらすいませんorz
引用返信 編集キー/
■21076 / inTopicNo.7)  Re[4]: 契約プログラミングと例外処理の使い分けについて
□投稿者/ ネタ好き (484回)-(2008/06/24(Tue) 14:49:22)
2008/06/24(Tue) 14:50:12 編集(投稿者)

皆様ご意見有難うございます。大変勉強になりました。
皆様のご意見を伺うに、assertは基本的にリリースで消え(オプションしだい)
例外はリリースで消えないというところが区分のポイントだと感じました。
一番assertの記述が詳しかったεπιστημηさんの意見から察するに、assertの場合は開発側の致命的なバグでリリースしてはならないバグを検出する目的で使用し、
他の皆様の意見から察するに、例外は開発側が想定しない使い方/想定外の出来事が起こった事を伝える目的で使用するという理解でよろしいでしょうか?
引用返信 編集キー/
■21077 / inTopicNo.8)  Re[5]: 契約プログラミングと例外処理の使い分けについて
□投稿者/ επιστημη (1116回)-(2008/06/24(Tue) 14:59:42)
επιστημη さんの Web サイト
> 皆様のご意見を伺うに、assertは基本的にリリースで消え(オプションしだい)
> 例外はリリースで消えないというところが区分のポイントだと感じました。

言わせてもらうと、だ。
「例外は人為的に握りつぶすことができる」

try {
  ...
} catch ( Exception ) {
  // 異常なーし♪
}

なんてのが一箇所でもあると例外によるあらゆる安全策は台無しになる。
で、こまったことにこんなのを恥ずかしげもなく書く阿呆がようけおんのや。

引用返信 編集キー/
■21078 / inTopicNo.9)  Re[5]: 契約プログラミングと例外処理の使い分けについて
□投稿者/ επιστημη (1117回)-(2008/06/24(Tue) 15:06:01)
επιστημη さんの Web サイト
> 他の皆様の意見から察するに、例外は開発側が想定しない使い方/想定外の出来事が
> 起こった事を伝える目的で使用するという理解でよろしいでしょうか?

ゴーマンかましてよかですか♪

想定してないなら、例外throwできるわけないわな。
十分想定できるからこそ、呼び出し側になんとかしてもらおうと
例外投げるのやな。

だったらこれは想定内だな。事前条件の定義域に収まってる。

あるいは:

そんな引数もらってもあたしゃどーすることもできません。
無視することすらできません。落ちることすら許されません。
なんてときに例外投げるんですな。

引用返信 編集キー/
■21079 / inTopicNo.10)  Re[6]: 契約プログラミングと例外処理の使い分けについて
□投稿者/ ネタ好き (485回)-(2008/06/24(Tue) 15:06:24)
No21077 (επιστημη さん) に返信
> > 皆様のご意見を伺うに、assertは基本的にリリースで消え(オプションしだい)
>>例外はリリースで消えないというところが区分のポイントだと感じました。
>
> 言わせてもらうと、だ。
> 「例外は人為的に握りつぶすことができる」
>
> try {
> ...
> } catch ( Exception ) {
> // 異常なーし♪
> }
>
> なんてのが一箇所でもあると例外によるあらゆる安全策は台無しになる。
> で、こまったことにこんなのを恥ずかしげもなく書く阿呆がようけおんのや。
>

確かにそれありえますね・・・
というか、遭遇したことがあります。
あれは確かに困ります。責任を取るのがいやなのでしょうねぇ・・・
それを考慮するとこの問題深いですね。
うーん非常に興味深い。
引用返信 編集キー/
■21080 / inTopicNo.11)  Re[6]: 契約プログラミングと例外処理の使い分けについて
□投稿者/ ネタ好き (486回)-(2008/06/24(Tue) 15:08:42)
No21078 (επιστημη さん) に返信
> あるいは:
>
> そんな引数もらってもあたしゃどーすることもできません。
> 無視することすらできません。落ちることすら許されません。
> なんてときに例外投げるんですな。
>

なるほど、そういう考えが一番しっくり来ます。
確かに想定できないのにthrow出来るはずがありませんしね♪
引用返信 編集キー/
■21081 / inTopicNo.12)  Re[6]: 契約プログラミングと例外処理の使い分けについて
□投稿者/ じゅで (61回)-(2008/06/24(Tue) 15:09:07)
> 言わせてもらうと、だ。
> 「例外は人為的に握りつぶすことができる」
>
> try {
> ...
> } catch ( Exception ) {
> // 異常なーし♪
> }
>
> なんてのが一箇所でもあると例外によるあらゆる安全策は台無しになる。
> で、こまったことにこんなのを恥ずかしげもなく書く阿呆がようけおんのや。

確かに沢山いますね。
本当になんの疑問も抱かずに、そんな事をしてくれるあほたれが。

その手の処理は、DBへの複数回のリトライ処理とかがあるような場合で、
特定のExceptionのみで、回数制限付きのリトライ処理の場合にしか
出てこないのに、なぜか、普通に何も考えずに握りつぶしますよね・・・

XMLのコメントつけておいても、平気で握り潰しやがります。
どれだけ苦労して書いてると思っているんだとorz

確かにそれを考えると止まった方がいいのかな?
けど、ユーザにメッセージを出す事を考えると、Exceptionをあげたくもある。

ただ、オブジェクトの機能としては、チェック機構はあるべきだと思うので、
リリースビルドで消えないオプション設定を付けておいてほしいです。

ただ、例外を何の考えもなく握りつぶすような人間が、そもそも
プログラムを組むなというような話のような気もする・・・
引用返信 編集キー/
■21085 / inTopicNo.13)  Re[7]: 契約プログラミングと例外処理の使い分けについて
□投稿者/ 774RR (197回)-(2008/06/24(Tue) 16:36:34)
組み込み系ではブツが動く(=金属の塊が回転したり振動したり)する関係で
異常なデータのままで動作を継続ってのはありえない。
なので明確に契約違反=バグ発見なら即マイコンリセットっす。
立場的には assert に近いですな。
デバッグのための遺言機能は残しておきますけど。

っていうか C みたいに throw な手段が無い言語ではどうすりゃいいんざんしょ。
素直に落ちるほうがいいとおもう
引用返信 編集キー/
■21088 / inTopicNo.14)  Re[8]: 契約プログラミングと例外処理の使い分けについて
□投稿者/ じゅで (62回)-(2008/06/24(Tue) 17:01:22)
> っていうか C みたいに throw な手段が無い言語ではどうすりゃいいんざんしょ。
> 素直に落ちるほうがいいとおもう

そういう場合は、デバッグ用の遺言残して素直に落ちるのが良いと思われます。

結局、何作るかによるんではないでしょうか?

assert使ってそのまま落ちなきゃいけない場合と
例外をスローして上でメッセージあげてから落ちなきゃいけない場合では、
動作が違うんだから、エラーの実装方法が違っていて当たり前なのかなぁ〜と思います。

私は、とりあえずユーザ側に何らかのエラーがあったよぉ〜というメッセージを
出す前提での意見です。

画面に出すなら、assert使わずに、ifで問い合わせて、Exceptionを投げる方が良いです。

# 本当にたまに問題外な人が、NUnitで流してて、Exceptionあげてるのに
# 握りつぶして正常とかぬかしてた事もあるので、一概に絶対良いとはいえませんが・・・orz
引用返信 編集キー/
■21089 / inTopicNo.15)  Re[9]: 契約プログラミングと例外処理の使い分けについて
□投稿者/ επιστημη (1118回)-(2008/06/24(Tue) 17:16:33)
επιστημη さんの Web サイト
> 結局、何作るかによるんではないでしょうか?
ま、そゆことなんでしょけど。

呼び側 : 問題に対処できるが検出できない
呼ばれ側: 問題を検出できるが対処できない

って両者を"えれがんと"に結びつけるのが例外なんだから
その対処ってーやつが"遺書を残して首吊る"か"ユーザを脅す"か
なんかわかんない呼ばれ側はとにかく"らめええぇぇ!"って伝いたい
(あとは頼むわ)から例外投げたわけよね。

その場ですこーんと頓死していいならassertでぢゅーぶん、と。

引用返信 編集キー/
■21093 / inTopicNo.16)  Re[10]: 契約プログラミングと例外処理の使い分けについて
□投稿者/ じゅで (63回)-(2008/06/24(Tue) 17:30:48)
> って両者を"えれがんと"に結びつけるのが例外なんだから
> その対処ってーやつが"遺書を残して首吊る"か"ユーザを脅す"か
> なんかわかんない呼ばれ側はとにかく"らめええぇぇ!"って伝いたい
> (あとは頼むわ)から例外投げたわけよね。

まさにExceptionは、あとは頼むはですね。

結局、Exception投げたいのって、ユーザに対して、なんらかのメッセージだして、
エラーコードから、説明書読ませたいとか色々あって、とりあえず画面だすのに、
復帰できなくても、とりあえずは後は頼むわって投げるしかないのですが、

そういうのが無い場合は、

> その場ですこーんと頓死していいならassertでぢゅーぶん、と。

の方が圧倒的にありだと思います。
というか、そうするべきだと思います。

ただ、assertで落としちゃう場合、Classとしてそれはありなのかなぁ〜と
思いますが、これもどの言語使うかで、そもそもオブジェクトって何よ?
って言語もあるんでありですね。

.NET系のクラスありきの言語で作成するなら"えれがんと"な方が私は好きですね。

引用返信 編集キー/
■21095 / inTopicNo.17)  Re[2]: 契約プログラミングと例外処理の使い分けについて
□投稿者/ シャノン (483回)-(2008/06/24(Tue) 18:07:09)
No21062 (επιστημη さん) に返信
>>または、契約プログラミングと例外処理についてはどう使い分けるべきだと思いますか?
>
> 契約プログラミングでの事前条件/事後条件は関数の定義域/値域が正しいかを確認するもの。
> 関数の定義域/値域が範囲外てーことは"バグ"です。
> 例外飛ばすのは"救済したい/できる"という意図の表れと考えます。
>
> で、僕は「バグは救済しちゃならん。その旨を速やかに報告し落ちるべし」をキホンとしてます。

ArgumentException を投げるのもナシですか。
C++ にも invalid_argument とかありますよね。
そんな例外に出番はない、と?
引用返信 編集キー/
■21096 / inTopicNo.18)  Re[4]: 契約プログラミングと例外処理の使い分けについて
□投稿者/ れい (676回)-(2008/06/24(Tue) 18:19:31)
No21070 (επιστημη さん) に返信
> えと、確かに契約プログラミング自体、Release時には消すように考えてるみたいです。
> 事前条件/事後条件にひっかかるのを"あってはならん"こととしてるならそれでいいのかもです。

ふみゅ。
契約プログラミングはそういう概念なのですか。
デバッグ時やコンパイル時の話しなわけですね。

だとするとやっぱり私はそれでは不十分なので
メソッドの頭でif+throw
メソッドの尻でassert
という形をとることが多くなるかと思います。

引用返信 編集キー/
■21097 / inTopicNo.19)  Re[3]: 契約プログラミングと例外処理の使い分けについて
□投稿者/ ネタ好き (487回)-(2008/06/24(Tue) 18:59:08)
assert文の使い方といえばデバッグテクニック徹底解説を読んで復習してみました。
そこで、筆者の上司がデバッグ時にはちゃんと動いていたのに、リリース時には動かないとクレームを言うエピソードが紹介されていました。その原因は全てのエラーチェックをassert文でしていたからリリースビルドでは「エラーチェックがまったく出来ない」事でした。
その話しとこの掲示板を読んで思ったのですが、お客や他の開発者に言うべきエラーの定義って難しいですよね。例外を出したら潰す馬鹿が居るし、assertを猿のごとく乱用する人が出現するし・・・
チーム開発の領域にまで話しが言ってしまいますよね。
そこで開発チームの話しまで解禁とします。
みんなでより熱く語り合いましょう。
引用返信 編集キー/
■21102 / inTopicNo.20)  Re[3]: 契約プログラミングと例外処理の使い分けについて
 
□投稿者/ επιστημη (1119回)-(2008/06/24(Tue) 22:04:52)
επιστημη さんの Web サイト
> ArgumentException を投げるのもナシですか。
> C++ にも invalid_argument とかありますよね。
> そんな例外に出番はない、と?

バグじゃなくてもありえない引数ってシチュエーションはありそうです。
ハードウェア(センサーとか)から読みだした値がとんでもねーとか。
理論的にはありうるけども実際はありえねーとか。

あるいはライブラリ内でエラーを検出したけども、
汎用ライブラリなのでその処理を勝手にどうこうすることはできず、
例外投げて呼び出し側にその対処を委ねるとか。

引用返信 編集キー/

次の20件>
トピック内ページ移動 / << 0 | 1 >>

管理者用

- Child Tree -