逃げる位なら「正しいプログラミングテクニック」を盲信しとけ!

いや、本当は盲信じゃなくてちゃんと理解すべき。でも理解不十分のまま、ふろむだ氏も言ってるなんて理由でそれに反する事を実行するよりは、盲信してる方が現実的にはよっぽど有益。というのは、彼が言っている事は、

  • 例外的な条件でのコードのあるべき姿の話
  • そのコードを取り巻く悪い状況に対する妥協の話

がごっちゃになっているから。これらを分ければ、前者の条件に該当することなんて本当に例外中の例外。プログラマは、悪い状況を招かない事にまず注力しなければ、いつまで経って低いレベルの妥協から抜け出せない。妥協の塊のせいで保守コストが上がり、そのせいで開発パワー不足が悪い状況を生み、また妥協…、のスパイラル。

「変数のスコープは狭いほど良い」

変数でもメソッド名でもクラス名でも言えることだが、単純に「スコープは狭いほどよい」という方針でプログラムすると、逆に保守性も可読性も悪いプログラムができあがることがけっこうある。

http://d.hatena.ne.jp/fromdusktildawn/20081026/p1

「けっこう」とか曖昧に言われても、それでは有益な情報ではない。コードのあるべき姿の話なのか、そのコードを取り巻く悪い状況に対する妥協の話なのか。

いろいろな箇所から比較的頻繁にアクセスする必要があるようなオブジェクトや機能がバインド(格納)された変数やメソッドのスコープをクラスやメソッド内のローカルにして、それを使うときは、いちいち各クラスやメソッドにパラメータ渡しのチェーンを繰り返して使うようにコーディングする人がいる。

http://d.hatena.ne.jp/fromdusktildawn/20081026/p1

ふろむだ氏は、これが駄目だと言っているが、これはコードを取り巻く悪い状況に対する妥協の話かと。状況自体をそんな事にならないように設計をするのがプログラマの本来の仕事。


どこからでも見るられる変数は、そのコードにとっての環境だったり対象だったり。それを適切に纏めてコードが無駄なく書ける状況にするのが設計のはず。まるで引数渡しが悪いかのような書き方だけど、まず対象を引数に渡すのは当然の事。関数の機能も明確で分かりやすくなるし、テスタビリティも上がるし、再利用性も上がる。環境も、どういうスコープ(コード上の話ではなく意味の話)のどういう環境なのかを見極めて、適切な形のコンテキストとして適切な範囲で持ち回る。


それが出来ておらずコードが汚くなっているのは、プログラマが仕事に失敗した状況であって、本当は再設計・リファクタリングすべき状況。とはいっても、そういう時はもうそんな事をしている時間がないのが現実だろう。ふろむだ氏が言っているのは、そういう状況への妥協策だと認識すべき。なってしまったものはともかく、プログラマの仕事はそうならないようにする事。ふろむだ氏が言っていたからなんて言って、これに甘んじていてはいつまでも状況が改善しない。

広いスコープからアクセスできるようにした方が正しいケースの代表的な例は、標準入出力ストリーム(stdinやstdout)がバインドされたグローバル変数の形で実装されているシステム変数や、Rubyのprintやpメソッドだろう。

http://d.hatena.ne.jp/fromdusktildawn/20081026/p1

それは、スコープがプロセス全体である環境の例*1。もともとOSが規定している意味としてそういうスコープのものなんだからそういうもの。普通のユーザ変数でそういうものは例外的。それでもスコープが広いものは、変数でなく定数にするなど、利用者の喧嘩が起きないようにする事で害はかなり小さくはなる。


なお「変数のスコープは狭いほど良い」のは、単一責務の原則とも密接な関わりがある(単一責務の原則は、なにもオブジェクト指向限定の話ではない。コードとして現れるすべての名を持つモノは、すべからく単一責務の原則に沿う事でそのメリットを享受する事が出来る)。プログラムにおいて、「それ(クラス、オブジェクト、メソッド・関数、…)」の責務を明確にして、「それは何?どういうもの?」をブレさせずに一貫させる事は、もっとも重要な事のひとつ。つまらないバグの相当部分が、これをブレさせた為に起きる*2。スコープが狭くて利用者が凝縮していれば、そんな取り違えのリスクも小さくて済むし、多数の利用者の多様なニーズに合わせて責務がゆがむリスクも小さくなる。

「同じロジックのコードを2度以上書くな」

5つ理由が挙げられているが、やはりほとんどが、

  • そのコードを取り巻く悪い状況に対する妥協の話

の話。もちろんKISS原則・YAGNI原則もちゃんと考えるべきではあるが、抽象化を分かりやすい形に出来ていないという問題を、抽象化を悪者にして対処とするのは如何なものか*3

プログラミング言語を極めるのが大切」

この節は元々別エントリだったのをホッテントリ入りのために後からマージしたものらしく、話のレイヤがいきなり飛んでる。しかし、これがふろむだ氏の話を理解する上で重要と思った。

結局のところ、ほとんどのコンピュータプログラムは、人間や社会のニーズや欲望を満たすために存在し、人間や社会の利害や感情の構造の組み立て(これも一種のプログラミングだ)と無縁ではいられない。

http://d.hatena.ne.jp/fromdusktildawn/20081026/p1

ようするに、ふろむだ氏は「意味があることにしか意味がないと思ってる((c)岩明均@風子のいる店)」んだと思った。社会的な意味において、

しつこいほどくりかえす。ユーザー視点において、 What to Code に比べたら、 How to Code などブロックをendで閉じるか}で閉じるかほどの意味しかないことを。

http://blog.livedoor.jp/dankogai/archives/51130751.html

というのは、弾さんの言う通り。極論すれば、そういう意味ではプログラムなんて「動けばいい」のだ。ふろむだ氏の発想の根本はこれなんだと思った。彼は有り余る知力で、プログラミングも高いレベルでこなすかもしれないが、プログラマではなく、結局、経営者なんだと。もちろん、経営者が悪いわけはない。それどころか絶対的に正しい。私だって、チームや部門の経営的観点で、プログラミングを妥協する。そうしなければ社会的に、意味を得ることが出来ないからだ。しかし私は、意味があることにしか意味がないとは、いい歳こいた今でも思っていない。


弾さんは、先に引用した言葉のあとには、以下のように続けてエントリを結んでいる。

しかし、その差が気にならない人が良いプログラマーになるということもまずないのだけれども。

http://blog.livedoor.jp/dankogai/archives/51130751.html

*1:ちなみに、元記事にスレッドの話がまったく出てこないのが気になった。スレッドはひとつの重要なスコープだと思うんだけど

*2:変数の意味するものを微妙に取り違えたり、関数の意味を勘違いしたり、いじってるうちに変えちゃってたり

*3:Monadとかそういうレベルの抽象概念をプロジェクト毎に発明というなら、むべなるかなという所だが、少なくともSI業界ではそういうチームの存在自体が例外中の例外だろう