Subscribed unsubscribe Subscribe Subscribe

SE Can't Code

A Tokyo based Software Engineer. Not System Engineer :(

差分デバッガに自動で単純化させればいい。

Python

仕事の大半は単調で退屈な作業ばかりだったりする。外から見れば華やかに見えるその仕事も、実は事務作業をコツコツとやる時間が多くを占めていて、中の人は意外とドロくさいと言うかもしれない。
僕が二つ前のプロジェクトで一番嫌いだった作業はただただ単調な試験だった。その試験の中でも一番憎かったのが、SIerの代表的な作業といえる、エビデンスのためのExcel画面キャプチャだった。試験結果が出たら、スクリーンショットを撮り、Excelシートに画面キャプチャをする。それをひたすら繰り返す。最初これをやっていた時は頭がおかしくなりそうだった。

こんなことは続けてられなかったので、途中で自動化した。自動化してやるとストレスもなくなるし、早く帰れるし、いいことだらけだった(あとスキルも身につく)。入社1〜2年目の頃は自動化コードをよくPerlで書いていた。自動化の先にはストレスがない上に、小さな達成感があった(厳密に言うとこの頃の仕事に対するストレスは凄かったけれど、こと単調作業に対しては解消されていた)。こういった単調な作業は非常にストレスになるし、なによりもこんなのに時間を取られるのはとても馬鹿らしい。

そして、それはバグの解析にも同じことが言える。
大きなコードにバグが入り込んだ時、バグ発生の原因となる箇所を探すのはなかなか骨が折れる。連鎖的にエラーを引き起こしている場合はさらに元を辿るのが難しい。けどしょうがいない、コードを早く解析してバグを直さないとPLに怒られちゃう。じゃあどうやって原因を特定すればいいのか、それはどんどんコードを削って単純化していけばいい。膨大なコードの中から少しずつコードを削っていき、そのたびにプログラムを走らせる。エラーが出れば、削ったコードの中に原因は無かったのだろう。次は削ったコードの中からまたさらにコードを削っていく。それを繰り返す。そうすればいずれバグの原因となっている箇所に辿り着く。

これは一番原始的でシンプルな解析方法だけれど、これを人の手でやるとなるとなかなか骨が折れる。非常に疲れるし、退屈な作業でしかない。たぶん僕だったら頻繁に散歩に出かけて外の空気を吸いにいくと思う。

こんなストレスが溜まることはコンピュータにやらせてやればいい。
コンピュータなら、自動的に差分デバッグを行い、単純化を実現出来る。

<差分デバッガ>

このコード上で定義しているバグは、<SELECT>であり、正規表現で一致した文字列に対してFAILが発生する。インプットとして文字列'<SELECT>foo</SELECT>'を渡して、<SELECT>を探す。
やっていることは単純で、まずはコードを半分に分けて、それぞれに対してPASS/FAIL判定を行っている。つまり切り分けを行っているだけなのだけれど、どちらにバグが潜んでいる切り分けられたら、さらに細かく切り分けを行う。切り分ける単位をサブセットと呼ぶが、このサブセットの粒度を変更させていくことで、バグの原因箇所を厳密に特定している。
最初のサブセットはそれの半分とし切り分けを行うと、片方でFAILが発生して、もう片方には問題が無いことがわかる。FAILが発生した10文字の文字列に対して、また同様のサブセットで切り分けを行うと、2分割された両方ともFAILが発生しない結果となる。これはサブセット単位が大きかったためである。そのため、次はサブセットの粒度をさらに細かくしていく。結果として、サブセットが2であった時の差分デバッグ<SELECT>が発見されることになる。

<結果>
sotoshigoto@soto:~/workspace/SofwareDebugging$ python simplifyDebugger.py 
'<SELECT>foo</SELECT>' 20 FAIL
'o</SELECT>' 10 PASS
'<SELECT>fo' 10 FAIL
'CT>fo' 5 PASS
'<SELE' 5 PASS
'ELECT>fo' 8 PASS
'<SECT>fo' 8 PASS
'<SELT>fo' 8 PASS
'<SELECfo' 8 PASS
'<SELECT>' 8 FAIL
'ELECT>' 6 PASS
'<SECT>' 6 PASS
'<SELT>' 6 PASS
'<SELEC' 6 PASS
'SELECT>' 7 PASS
'<ELECT>' 7 PASS
'<SLECT>' 7 PASS
'<SEECT>' 7 PASS
'<SELCT>' 7 PASS
'<SELET>' 7 PASS
'<SELEC>' 7 PASS
'<SELECT' 7 PASS
'SELECT>' 7 PASS
'<ELECT>' 7 PASS
'<SLECT>' 7 PASS
'<SEECT>' 7 PASS
'<SELCT>' 7 PASS
'<SELET>' 7 PASS
'<SELEC>' 7 PASS
'<SELECT' 7 PASS
<SELECT>

差分デバッグを使えばバグの原因箇所の特定を自動的に単純化してくれる。上記のコードは本来ならアサーションを使って拾いあげたりする使い方になると思う。
こういった具合で単調な作業は出来る限り排除しよう。

早く家に帰って家族と一緒に過ごしたり、自分の時間を大事にすること。

Remove all ads