ふつーのプログラマです。主に企業内Webシステムの要件定義から保守まで何でもやってる、ふつーのプログラマです。

ハローサマー、グッドバイ(12) デバッグ・フォー・ビギナーズ

»

 他人が書いたソースは読めない、と思い込んでいるエンジニアが大勢いる。もちろんこれは正しくない。他人が書いたソースが読めないとしたら、書く方が正しく書く努力を怠っているか、読む方が読もうとする努力を怠っているかのどちらか、またはその両方だ。

 インシデントZ前、ぼくが働いていた業界では、リーダブルなコードを書こうという気運が少しずつではあるが広まりつつあり、いくつかの良書の出版がそれを後押ししていた。ぼく自身、たとえ納期に追われる激務の最中であっても、読みやすいコードを書くことが、結局は顧客も含めた関係者全員の利益となるということを学び、それを実践してきたつもりだった。たとえば、実際にやるかどうかはともかく、ユニットテストにかけやすいメソッドを書く、といった類いのことだ。

 ソリスト・システムのコーディングをしたプログラマたちは、それらの良識とは対極の考えを持っていたらしかった。いや、むしろ、何の考えも持っていなかったというべきか。

 ようやく待ち望んだソースを入手したぼくは、その膨大な数に驚きながらも、喜び勇んで適当なクラスを開いてみた。目に飛び込んできたのは、日本語ではない数行のクラスコメントだった。

 「え?」

 スクロールしてみると、修正履歴らしいコメントが100 行ほど続いていた。2、3 行だけ英語のコメントがあったが、残りはほとんど中国語のようだった。ぼくは思わず天を仰いだ。他のソースをいくつか開いてみたが、大半が英語と中国語で、日本語は数えるほどしかなかった。コメントから中身を把握できるのではないか、という希望が霧消していった。

 「うーん」ぼくは思わず唸った。

 「どうかした?」聞き咎めた島崎さんが訊いてきた。

 「その、コメントが......いえ、なんでもないです」

 日本語のコメントがほとんどないということは、国内で実装が行われていないことの証左だ。ひょっとすると、ソースが事前に提供されなかったのは、これが原因なのかもしれない。だが、この場でそんな事実に言及したところで、Z判定ロジックのバグフィックスに役立つわけでもない。

 とにかくコードを読んでみるか、とぼくはクラスの中から、末尾がImpl になっているものをいくつかピックアップし、最初の1 つを開いてみた。やはり中国語のコメントが並んでいる。せめてコーディングの傾向だけでも掴めないか、とメソッドの中に進んでいくと、何の処理だかわからないが、いきなりこんなコードに出くわした。

Boolean smart = null;
for(int vet98=78;vet98<DTROK_BG_DOWN_LIMIT;vet98++) {
switch(vet98) {
case 78:
smart = jeb78(vet98,true,null) | true;
break;
case 88:
jev88(vet98,vet98,DTROK_BG_DOWN_LIMIT,0);
break;
case 89:
jev89(vet98,vet98,DTROK_BG_DOWN_LIMIT,1);
break;
case 99:
throw new OxyMildException(OXY_MILD_EXCEPTION_MSG);
default:
break;
}
if(smart) {
break;
}
}

 意味不明なコーディングだ。for ループ内にswitch を入れていることもそうだが、これだと最初のメソッドしか実行されない気がする。何か隠された意図があるのかと、何度か読み直してみたが、頭が混乱しただけだった。

 そのクラスを閉じて、別のクラスを開いた。コーディングしたのは別のプログラマのようだが、やはり同じような意味なしコードが頻出している。

WifiBlockLogging ab_ooops_1 = new WifiBlockLogging();
ab_ooops_1 = getBlockSlideOffen3(lifeElec);
ab_ooops_1 = new WifiBlockLogging();

if(true) {
double retVal = 3.14159d;
int retRat = 13;
retVal = bloodConditionFilter(2);
retVal = 0;
}

String str_50_1 = new Integer(Integer.parseInt(SON_O_ALB)).toString();
if(Integer.parseInt(str_50_1) == 64 || (Integer.parseInt(str_50_1) > 63 && 91 > Integer.parseInt(str_50_1))) {
return;
}

long brkBoo = -1L;
while(brkBoo == -1L) {
brkBoo = zzUnDoRUNs_LifePoint(brkBoo);
if(brkBoo == -1L) {
brkBoo = brkBoo + 1L;
}
}

 日本に限らず、世界のほとんどの国では、Z戦争で大きな被害を受けた生活インフラの復旧が優先されていて、IT 業界は今のところ斜陽産業だ。おそらくベテランプログラマの多くが転職を余儀なくされただろうから、人材不足なのは理解できる。しかし、それを差し引いても、新人研修レベルのコードが多くて、怒りすらおぼえるソースだ。明らかにoff-by-one エラーになっているfor 文や、例外の握りつぶしなどはまだ微笑ましい方で、

private static final int DART_INFRA_WAVE_ONE = 1;
private static final int DART_INFRA_WAVE_TWO = 2;
private static final int DART_INFRA_WAVE_THREE = 3;

と、1 から256 までの数値を定数宣言しておいて、どこでも使用されていなかったり、数百行のデッドコードが放置されていたりと、意図的に難読化してあるのではないかと思ったほどだ。JDK1.8 ベースだというのに、インシデントZ前に普通に使われるようになっていたラムダ式も全く使用されていない。

 何よりもソースに統一感というものが感じられない。変数名の付け方や、インデント方式など、最低限のコーディングルールすら設けられていないのだ。国際的大企業からの納品物とは思えない。典型的な「動けばいい」プログラムだ。

 以前に一緒に仕事をした別会社のプログラマが、打ち上げの席で言っていた言葉を思い出した。同じ横浜市内の小さなシステム会社だったが、技術力では定評のある会社のトッププログラマだった人だ。

 「昔ならともかく、動くだけのソースを書くのは簡単なんだよね、今どきは。サンプルなんかネットにいくらでも転がってるから、それをコピペすれば、とりあえず動くものはできちゃう。でも、俺たちはこれで金もらってるプロなわけだから、それだけじゃいかん、と思うんだよね。エンドユーザが求めてるのが、動くシステムであることはもちろんなんだけど、ただ動くだけじゃなくて、ちゃんと正しく動くってことが重要なんだよ。仕様変更や追加に強い作りにするとか、ソースの可読性を上げるとか、エラーに対して予防線張っとくとか、そういうことも含めてね」

 その人が、このソースを見たら、血管が何本かブチ切れるに違いない。

 Z探知関連のパッケージ、zDetectionSubsystem の中には、1855 個のインターフェースとクラスが含まれていた。数日間の作業時間と、必要なドキュメント、できれば高解像度のデュアルモニタがあれば、ソースを読んでいくことで原因の糸口ぐらいは掴めたかもしれないが、現実的にぼくの目の前にあるのは、短い時間と貧弱なデバッグ環境だけだ。しかも、このノートPC にインストールされているEclipse は、極端なまでにソリスト用カスタマイズが施されているらしく、コンパイラのエラー/警告が全て「無視」に設定されていたし、プロファイラなどのツールも無効になっていた。Null ポインタアクセスや、同値比較などがあっても、エディタ上でアラート表示することさえできない。何かの罰ゲームか、これは。

 ぼくが読みづらいソースと格闘している間にも、指揮車両とバンド隊員たちは移動を再開し、みなとみらい地区へ向かって、綱島街道を時速4 キロ弱で南下していた。事前にシミュレーションが提供されたといっても、隊員たちのソリスト端末にインストールされている機能とは相違が多数あったらしく、島崎さんの元には数分おきぐらいに隊員の誰かから、機能や使用方法について問合せが入っていた。もっとも島崎さんはマニュアルを参照することもなく、迅速に対応していたので、大きな不満に発展することはないようだ。

 役立たずのドローンは5 分ほど飛行させた後、臼井大尉の命令で指揮車両に戻されている。本来であれば、赤外線、超音波、テラヘルツ波、映像解析、音響解析を組み合わせて、半径400 メートル以内で75%、800 メートルでも60% の精度で誤差1 メートル以内のZ分布マップをリアルタイム更新できるはずなのに、ほとんど正常に機能しなかったからだ。機能しないだけならともかく、明らかに何もない路上にZマークを自信満々で点滅させたり、バンド隊員の真横を数体のZが同じ速度で進んでいるとアラートを上げたりしていて、それらの偽情報に気を取られるぐらいなら、ない方がいい、と臼井大尉が判断したからだ。間違ったコメントなら書かない方がいいのと同じだ。

 10 分ほどかけて、20 本ほどのソースを読んだ後で、というより、読むのを断念した後で、ぼくは方針を変えることにした。

 「胡桃沢さん」ぼくは仏頂面の胡桃沢さんに話しかけた。「デバッグ環境はどうやって起動するんですか?」

 胡桃沢さんはうるさそうに顔をしかめたが、ぼくの質問を露骨に無視することもできかねたようで、「知らん」とは言わなかった。

 「まず仮想環境を生成する。VP というメニューがあるだろう。ダイアログが開くから、リソースを割り当てて実行する。少なくともコア数2、メモリ2G は必要だ。仮想環境が立ち上がったら、必要なサブシステムをロードして......」

 言われた通りに仮想環境を作成すると、Z探知サブシステムのテスト環境が立ち上がった。幸いなことにメニューは日本語化されている。半径1 キロの円形の仮想空間に、地形、建造物、天候、時間帯、気温など様々なエレメントを追加してテスト環境を構築した後、Zをランダム、または任意の位置に配置する。後はソリストシステムコアと、ソリスト端末、そして広域情報収集オブジェクトを追加すればいい。つまり指揮車両、バンド隊員、ドローンだ。

 エレメントは手動で配置することもできるが、現状を忠実に再現することが目的ではないので、用意されているテンプレートを使用することにする。都市パターンJ20-0-98-a を選ぶと、高層ビルが少なく、2 階建てから3 階建ての一般住居が多いパターンの仮想空間が生まれた。10 体のZをランダムにばらまき、指揮車両、バンド隊員、ドローンを中央に配置する。さらに天候パラメータを晴天、気温パラメータを30 度に設定した。

 「このテストツールはよくできてますね」ぼくは、様子を見に来た島崎さんに言った。「使いやすいです。レスポンスも速いし」

 「ああ、それは確か、3DCG ソフトを作ってた会社に発注したんだったかな」

 「言われてみれば、Vue に似てますね」

 テストツールは、メニュー体系や、グラフィック、応答速度、環境エディタと、どこを取っても使いやすく作られている。ソリスト本体が、これぐらいの完成度だったらよかったのに、と思いながら、テストを実行した。

 結果は1 秒以下で出た。ランダム配置したZが見事に全て探知され、別ウィンドウの結果画面に表示されている。

 まあ、これは当然だ。この程度で探知不能になるのであれば、さすがに出発前に修正されているだろうから。ぼくは結果をクリアすると、今度はトレースを有効にして再実行した。

 結果は同じなので結果画面はすぐに閉じた。ぼくが見たかったのはトレースログだ。メニューから「ログ表示」を選択すると、今の一連の探知シミュレーションで動作したクラス名とメソッド名がずらりと並んだログが表示された。ざっと6000 行以上だ。

 もう少し範囲を絞っておきたい。どこかにステップ実行のような機能があるはずだ。ぼくは実行メニューの中から「デバッグ実行...」を見つけてクリックした。「ステップイン/アウト」があったので実行しかけたが、その下に「タイムライン」というのがあったので試してみた。実行するとタイムラインを表すバーが表示され、その上をグリーンのアイコンがのろのろと進んでいく。下に一時停止、再開、停止のボタンがあり、コントロールができるようだ。

 このテストの実行時間は463 ミリ秒で、1 ミリ秒単位で停止等が可能なようだ。ぼくは50 ミリ秒毎に一時停止点を設定すると、再実行した。最初の一時停止点で止まったとき、結果画面を表示し、まだZが探知できていないことを確認する。実行を再開し、次の一時停止点で同じことを繰り返す。最初のZが探知されたのは、300 ミリ秒から350 ミリ秒の間で、残りが探知されたのは次の50 ミリ秒の間だった。

 もう一度トレースログに戻り、300 ミリ秒付近で実行されているクラスをピックアップした。最初の1つは、PatternAnalysysZopticalBuilder158Impl。まずは、ここから始めるべきだろう。ぼくはソースを開いた。やはり中国語のクラスコメントだ。

 「どう?」島崎さんが訊いてきた。「何とかなりそう?」

 「とりあえず、とっかかりは。これから深く潜っていきますが」

 「どれぐらいかかりそうかな。あっちの人が......」島崎さんはちらりとボリスの方を見た。「気にしてるみたいなんだよね。目安だけでもわかるといいんだけど」

 わかるもんか、と思ったが、島崎さんの立場も理解できる。ぼくは少し考えて答えた。

 「30 分後に一度経過報告します」

 「よろしくね」

 島崎さんは戻っていった。ぼくはペットボトルの水を飲むと、読みづらいソースを追い始めた。

◇ ◇ ◇ ◇ ◇ ◇ ◇ ◇ ◇ ◇

 30 分後、隊列は菊名駅付近に近づいていた。予定より遅れているのは、ソリストのZ探知ができないため、進行速度を落とさざるを得なくなったためだ。加えて、Zの群れをやり過ごすために、何度も停止している。

 「鳴海さん、そろそろ30 分過ぎたけど」島崎さんが申しわけなさそうに言った。「どんな感じ?」

 「少しわかってきたんですが......」

 ぼくが追っていたのは、Z判定のアルゴリズム部分だった。まだ完全に追い切れてはいないが、ソースから推測できた限りではポイント方式で判定を行っているようだ。まず、リアルタイムで更新されるマテリアル――つまり素材――に、それぞれ異なる判断基準で、0 から255 のポイントをつける。測定不能なマテリアルを除外して、平均が180 ポイントを超えればイエローフラグ、200 ポイントを超えればオレンジフラグ、220 以上ならレッドフラグとなる。マテリアルは、ドローンからの各種情報の他、バンド隊員たちのヘッドセットに搭載されているセンサーやカメラからの情報も含まれる。

 「そこまでわかったなら、もう少しってとこ?」

 「それが肝心な部分は、jar ファイルに、つまりライブラリになってて、ソースが参照できないんですよ」

 jar ファイルにはソースを含めることができるが、これを作ったエンジニアはそうしなかったようだ。

 「それがないとできないの?」

 「そうですね。いろいろテストしてみて、その結果から機能を推測することはできますけど......」

 「ふーん。じゃあテストをやればいいのかな?」

 「そうなんですが、それにはちょっと時間がかかりますよ。マテリアルとなる映像や赤外線情報のテストデータが、各種パターン必要なんですけど、そんなのどうやって生成すればいいんだか」

 「今あるのは使えないの?」

 「それが、そうもいかなくて」ぼくはソースをスクロールした。「サーバにストックされているのは、生データじゃなくて、データベースの保存形式に変換されたデータなんです。だけど、Z判定に利用しているのは生データなんですよ。たぶんサーバの容量の問題だと思うんですけど......」

 「?」

 「つまりアナログ音源が必要なのに、MP3 データしか手元にないと言ったらわかります?」

 「うーん、ごめん。よくわからんね」混乱した顔の島崎さんは振り返った。「胡桃沢さん、ボリスさん、ちょっといいですか?」

 胡桃沢さんとボリスが顔をしかめながら近くに来た。ぼくは島崎さんにした説明を繰り返した。

 「じゃあ、生データを使ってデバッグすればいいだろ」胡桃沢さんは不機嫌そうな声で言った。「本番サーバを見にいくようにすれば......」

 「あー、ちょっと待ってください」ボリスが割り込んだ。「それはちょっと無理です」

 「あ?なぜです?」

 「えーとですね、まず作戦サーバ......つまり、本番サーバですな。そいつに接続できるのは、いわゆる本番用のデバイスだけなんです。つまり隊員たちのソリストとか、このCCV のコンソール類とか、デバイスID が登録されているものだけです。そのノートPC は演習用サーバにしかつながらないID がついてるんです」

 「このノートPC のデバイスID 登録を追加すればいいだけではないのですか?」島崎さんが訊いた。

 「それはここじゃできないんです」ボリスは日本人離れした仕草で肩をすくめてみせた。「作戦モードで起動しているので、デバイスの追加や削除は本部でしかできません。理由は言うまでもないと思いますが、実戦環境で敵に侵入されないためです」

 「それじゃあどうやってテストするんですか?」敵って誰だよ、と心の中で突っ込みながら、ぼくは訊いた。

 「ソースはダウンロードできたんだろう?」ボリスは明確に態度を変えた。「コードを読めばいいじゃないか」

 「肝心の部分がライブラリになっててソースはないんですよ」ぼくは冷静に答えた。「だから実際に動作させて確認するしかないんです。その部分のソースをもらえば読みますよ」

 「周辺のソースがあれば、コア部分がなくても何とかならんのかね」薄笑いがボリスの顔に浮かんだ。「うちのエンジニアなら、それぐらいのシミュレーションは昼寝しながらだってやってのけるがね」

 「すいませんね、無能で」

 「ほう、自己評価だけは正確なんだな」

 「まあまあ」島崎さんが割って入った。「他にテストする方法はないんですか?」

 「ないですね」

 「いや、待て」胡桃沢さんが額にしわを寄せて、島崎さんを見た。「確か、ヘッドセットサブシステムにはデータダウンロード用のUSB ポートがあるだろう。そこに直接接続したらいけるんじゃないか?」

 「確かにありますが......」島崎さんは首を傾げたが、何かを思い出したように顔を上げた。「ああ、そういえば、うちの実装班も最後のテスト工程のときは、バンド隊員のヘッドセットを借りてた気がするなあ。誰かに貸してもらえばいいんじゃないかな」

 「でも、ヘッドセットサブシステムのインターフェースって、BIAC ですよね」ぼくは指摘した。「ぼくじゃ使えないですよ」

 BIAC インターフェースは、装着者の頸部にマイクロマシンで形成された回路から信号を読み取るのだから、バンド隊員でなければ無理だ。

 「緊急用のマイクロマシン・セットアップキットならあるぞ」ボリスがニヤニヤ笑いながら言った。「本来ならクリーンルームで医療技術者が投与するんだが、これなら素人でも打てる。なんならオレが打ってやってもいい」

 「ご親切にどうも」こいつを相手にするのはやめた方がいい、と悟ったぼくは素っ気なく答えた。「遠慮しときますよ」

 「そうなると」島崎さんが考えながら言った。「隊員の誰かに、テストに協力してもらうしかないね」

 「そうですね......」とはいえ、誰に頼めばいいのか。

 「うん、いいよ」ぼくの顔に浮かんでいたであろう逡巡を読み取ってくれたらしく、島崎さんは軽く笑った。「私から頼んでみるから」

 「すいません」

 島崎さんは前部に歩いて行くと、臼井大尉に話しかけた。最初、臼井大尉は顔をしかめていたが、島崎さんの交渉能力のおかげか、やがて頷いた。

 「ビーン」臼井大尉は谷少尉を呼んだ。「ソリストのデバッグに、隊員を1 人使いたいそうだ。鳴海さんに付けたのは誰だ?」

 『......ブラウンアイズです』

 「じゃあブラウンアイズ、任せるからな」

 ブラウンアイズの返事は1 秒ほど遅れて聞こえた。このタイムラグは、BIAC インターフェースが拾ったデータを、指揮車両のサーバに転送して、音声データにデコードするのに要する時間だと後で知った。

 『......え、イヤですよ』

 「すまんが命令だ」臼井大尉は本当にすまなさそうな声で言った。「今からそっちに行かせる」

 「え!」ぼくは思わず声を上げた。「外でやるんですか?」

 「当然だ。ブラウンアイズをこっちに乗せれば、分隊の活動に支障が出るからな。Z歩行は練習したと聞いているが?」

 「そりゃしましたが......」

 「なら問題ないだろう」

 「いやいやいやいや、問題ですよ。歩きながらどうやってデバッグとかするんですか?」

 「休憩を兼ねて20 分停止する」臼井大尉はタブレットで何かをチェックしながら言った。「その間に必要なデータを取ってくれ。それで足りない場合は、また考えよう」

 「でも......」座っているだけ、という話はどこ行った?

 「サンキスト」臼井大尉はぼくの抗議には耳も貸さず、ドライバーに言った。「その先の菊名駅前交差点の中央で停めろ。ビーン、グレイベア、前方の交差点で20 分間停止する。周囲を警戒させろ。歩道橋の上もな。ただしブラウンアイズは鳴海さんのデバッグ作業に協力だ。他の隊員は、Zに二人の邪魔をさせるな」

 2 人の分隊長から、それぞれ短い応答が返ってきたと同時に、微かに聞こえていたモーター音が低く変化した。スピードが落ちてきているのだ。

 「おい」胡桃沢さんが何かをぼくに放った。「それ使え」

 反射的に受け取ったのは、長さ2 メートルほどのUSB ケーブルだった。A 端子とマイクロB 端子になっている。

 「挿せばデバイスは認識する。どういうデータを取ればいいのかわかってるんだろうな?」

 「ええ、まあ。ヘッドセットカメラの映像、特に明暗差が微妙な場所」ぼくは指を折った。「インフラレッドモードで温度差が微妙に異なる地点、超音波のエコーデータってとこです」

 胡桃沢さんは小さく鼻を鳴らすと戻っていった。少なくとも間違ってはいなかったらしい。

 「気をつけて」島崎さんがぼくの肩をぎゅっと握った。「無線でデータが取れればよかったんだけどね」

 「次のバージョンでは、ぜひそうしといてください」

 「30 秒後に停車するぞ」臼井大尉が告げた。「準備はいいか?」

 できてません、と言いたいところだが、そんなことをしても問題を先送りにするだけだ。ぼくは渋々頷いた。

 「OK です」

 「ああ、水分補給しておいた方がいいぞ」

 ぼくは言われた通り、ペットボトルから2口ほど飲んだ。中身はぬるくなったスポーツドリンクだ。

 「停止まで5秒だ。3、2、1、マーク」

 電子ロックが外れる音とともに、ドアが横にスライドした。

(続)

Comment(21)

コメント

noname

> 意味不明なコーディングだ。for ループ内にswitch を入れていることもそうだ
> が、これだと最初のメソッドしか実行されない気がする。
逆でswitch抜けるけど、Forで繰り返すので、必ずOxyMildExceptionをスローしそう。

通りすがり

いや5行目で smart が必ず true になるからループは抜ける。
まぁ、5行目のお尻のは見落とすのも無理は無いな。

noname

確かに。
でも必ずSmartがTrueは違う気がするけど

通りすがり

思っていた以前の問題で躓いていたのか。
まぁ jeb78() が中で例外吐く可能性とかあるから、厳密に必ずでは無いが、多分そういう事を言っているのでは無いと思うので、念の為。

5行目のお尻はよく確認した?

noname

とりあえず、あのソースの自分の解析結果は
・最初のメソッドが実行される
・smartの評価でNullPointerException
ですね

※ソースの解析、特に人が書いたものを読むとき、説明するときに”必ず”や”絶対”というワードを使ってる場合、ほぼほぼ落とし穴にはまっているという、自分の経験則から喧嘩腰なレスになってしまいました。申し訳ないです。

dotJ

最初のメソッド(jeb78)が例外も吐くとか、null を返すことがなければ、結果がtrueでもfalseでも、smartは必ずtrue になるんじゃないかな。

通りすがり

>>nonameさん
必ずの表現を不快に思われたのであれば申し訳ない。

一応、私の思う動作としては、
・最初のメソッドが実行される
・その行の "|" 以降が評価されて全体として true が返る
・smart に true が代入される
・smartの評価でループから抜ける
です。

noname

>・最初のメソッドが実行される
>・その行の "|" 以降が評価されて全体として true が返る
>・smart に true が代入される
>・smartの評価でループから抜ける

これに、Forループに入らない場合を追加した(定数設定値エラーかな?)のが上記書いた私の結果ですね

※でも懐疑的にソースを読むことは大事だと思うです。そこだけは譲れないです・・・

ほぼほぼw

| true 最強

いずれにしろvet98が79以上の値を取ることはないでしょ。

通りすがり

ループが回らないのてあれば、ループの中にある smart の評価はされないのでは?
まぁ、その後に使わないとも限らないので、危険であるのは確かですね。

懐疑的にソースを読むことは大事と言うのには同意します。

noname

>ループ内でsmart評価

確かに・・・ボロボロだ・・・OTL

aetos

> zDetictionSubsystem

Detection だと思いますが…わざと?

aetosさん、どうも。
もちろん、わざとです。つまり、単語のスペル自体もいい加減なソースという……
いえ、ウソです。間違いです。

ちょ兄

nonameさん

DTROK_BG_DOWN_LIMIT<=78だった場合、確かに後ろのメソッドでsmartを参照したらnull pointerですね。
>・最初のメソッドが実行される
>・smartの評価でNullPointerException
というのは、連続した事象ではなく

・最初のメソッドが実行される(そしてループを抜ける)
または
・(その後の処理で)smartの評価でNullPointerException
という意味なら納得です。

※smartのスコープがループの外ってのが怪しいし。

yen

1step何円っていう契約だったのかしら

oomasa

Step換算の契約だったらもっとコメントが多いかとw

know

ステップ数換算の場合、コメントは除外しないかな?
そういうツールがあったような。

tako

外に出た鳴海さんを襲ったのは変わり果てたサードアイの東海林さんであった・・・とならないことを祈るw

とり

敵に侵入される?
東海林さんがZ化してるとか?

p

東海林さんワロタ

イエーガー

なるみもいいとばっちりだが島崎も大変だなぁ・・・、ちゃんとボリスに天罰が下ることを期待して読み進める

コメントを投稿する