第8回「Linuxのしくみ」読書会に参加しました

7/18 に開催されたNSEGの「Linuxのしくみ」読書会の第8回に参加しました。参加者7名。

nseg.connpass.com

今回は第8章の最初から最後まで読みました。最終回でした。

個人的な収穫

  • posix_memalign() という関数を知った。

誤植等

  • p.248 「①」「②」ときて何故か「③」じゃなくて「(3)」。あと白抜き文字じゃない。
  • p.249 「①、②のとこんろです」→「①、②のところです」
  • p.252 「sdb -x -p sdb 1」→「iostat -x -p sdb 1

おわり

これで「Linuxのしくみ」の読書会は終了です。

非常に誤植が多かったことが残念ですが、とても良い本でした。

Linux の プロセス、CPU、メモリ、ストレージ管理の基本がわかります。 サーバーの性能が出ないといった時の調べ方の助けにもなると思います。

[試して理解]Linuxのしくみ ~実験と図解で学ぶOSとハードウェアの基礎知識

[試して理解]Linuxのしくみ ~実験と図解で学ぶOSとハードウェアの基礎知識

NSEG読書会として次に何の本を読むかは未定です。次回はたぶん8月のお盆明けくらいになるんじゃないかと思います。

第7回「Linuxのしくみ」読書会に参加しました

7/4 に開催されたNSEGの「Linuxのしくみ」読書会の第7回に参加しました。参加者8名。

nseg.connpass.com

今回は、第7章の途中(p.179)から第7章の最後まで読みました。

個人的な収穫

  • ext4 でディレクトリクォータが使えるのは知らなかった。どうやって設定するんだろう。
  • strings コマンドに -t というオプションがあるのは知らなかった。
  • bash の $((...)) を知った。((...))$ をつけた感じか。一貫性はある。
  • Btrfs は名前しか知らなかったけどかなり便利そう。RHELはなんでサポートやめたんだろう。

誤植等

  • p.204 図7-12の①に hoge ファイルが無い。
  • p.216 "「lost+found」はext4の作成時に必ず作られるファイル" → ファイルじゃなくてディレクトリ。
  • p.218 "このとき「size」マウントオプションによって最大サイズをしています" → "最大サイズを指定しています" かな。
  • p.221 "/sys/fs/cgroup/memory 以下のファイルに読み書きによって制御" → "ファイルの読み書きによって制御" かな。

その他

  • 昔のSolarisにはunlinkというコマンドがあって、ディレクトリエントリもサクッと消してくれるので、簡単にファイルシステム不整合を起こすことができて便利w
  • p.210 "「どのファイルシステムにも共通して存在するのが「fsck」というコマンド(ext4なら fsck.ext4、XFSならxfs_repair、Btrfsなら「btrfs check」)です" という記述が妙な気がする。「fsckコマンドの実体は」ということだとは思うが。
  • p.213 px ax | grep bash で端末を調べてるけど、tty コマンドでいいのでは。

次回は7/18です。おそらく最終回になると思います。

nseg.connpass.com

第6回「Linuxのしくみ」読書会に参加しました

6/20 に開催されたNSEGの「Linuxのしくみ」読書会の第6回に参加しました。参加者5名。

nseg.connpass.com

今回は、第6章の途中(p.170)から第7章の途中(p.197)まで読みました。

個人的な収穫

  • vm.dirty_writeback_centisecs, vm.dirty_background_ratio, vm.dirty_background_bytes, vm.dirty_ratio, vm.dirty_bytes 等のパラメータを知った。
  • なんとなくしか知らなかったハイパースレッドの仕組みを知った。

誤植等

なんと!今回は誤植等がありませんでした!

しかし今まで報告した大量の誤植等の扱いはどうなってるんだろう…。

その他

ページキャッシュが効いてる状態で dd で書き込むと、本の記述と異なり、すぐに pgpgout/s が出てしまいました。 その時は何故かわからなかったんですが、読み進めて、おそらく vm.dirty_background_ratiovm.dirty_ratio の影響だと思い至りました。 1GBも書き込むと、メモリが少ないとすぐにこれに引っかかっちゃいますね。


次回はたぶん7/4です。

第5回「Linuxのしくみ」読書会に参加しました

6/6 に開催されたNSEGの「Linuxのしくみ」読書会の第5回に参加しました。参加者7名。

nseg.connpass.com

今回は、第5章の途中(p.135)から第6章の途中(p.170)まで読みました。

個人的な収穫

階層型ページテーブル、ヒュージページについては知りませんでした。

誤植等

  • p.139 誤植というかプログラムのバグだけど、プロセスIDが5桁未満の場合は ps の出力が空白で始まるので、grep ^%d に適合せず出力されない。
  • p.141 「親プロセスと子プロセスでメモリで共有されているメモリは」
  • p.144-145 プロセスBの仮想アドレスから物理メモリ500に不要な線がある。
  • p.145 PDF版第2版 は 145ページが重複していて146ページがない。[追記] 2018/06/23時点では修正されています。
  • p.152, 154 「物理アドレス」であるべきところが「下位のページテーブル」になっている。
  • p.155 「mdadvise」→「madvise」

その他

  • プロセスサイズだけでは実際のメモリ使用量はわからない。/proc/*/smaps の Pss を見れば目安になる。という話をしました。
  • 誤植つらい。p.145 が重複してるって何事??? 実はこの2つのページには1箇所違いがあります。誤植を直してページを差し替える時に間違って p.146 を消して修正後の p.145 を入れてしまったのかな…。

f:id:tmtms:20180606223508p:plain

[追記] 2018/06/23時点では修正されています。


次回は6/20です。

nseg.connpass.com

第4回「Linuxのしくみ」読書会に参加しました

5/24 に開催されたNSEGの「Linuxのしくみ」読書会の第4回に参加しました。参加者4名。さらに減った!

nseg.connpass.com

今回は、第5章の途中(p.98)から第6章の途中(p.135)まで読みました。

個人的な収穫

今回の範囲では特に知らなかったことは無かったです。

誤植等

  • p.104 「before invalid access」のフォントが異なる。
  • p.130 誤植じゃないけど、sarの結果の1行が折り返されてて見にくい。興味があるのは kbmemused だけなのだから、右側は折り返さなくて見せなくてもいいような。

その他

ページテーブルのアドレスが「100-200」「200-300」となってて、「200」がどっちのページかわかりにくいという意見がありました。まあちょっと考えれば「100-199」「200-299」という意味だとわかるし、たぶん /proc/*/maps の出力に合わせたんだと思うんですが、説明があった方がわかりやすかったかも。

p.101の説明が「ページフォールトが発生するとSIGSEGVが起きる」みたいに読めてしまって違和感。説明も「物理メモリ未割り当て」ページのように書かれてるけど、p.122の用語での「プロセスには未割り当て」の状態のはず。「物理メモリ未割り当て」だとp.122の「プロセスに割り当て済みだが物理メモリは未割り当て」だと思ってしまいそう。

そういや昔のSolarisのmalloc()mmap()じゃなくてbrk()を使ってたなーと思いだした。そのためfree()してもプロセスサイズは減らなかった。mmap()を使うmalloc()を作ってLD_PRELOADで差し替えて遊んだりしてた。懐かしい。


次回は6/6です。

nseg.connpass.com

第3回「Linuxのしくみ」読書会に参加しました

5/9 に開催されたNSEGの「Linuxのしくみ」読書会の第3回に参加しました。参加者6名。急に減った!

nseg.connpass.com

今回は、第4章の途中(p.65)から第5章の途中(p.98)まで読みました。

個人的な収穫

  • sar の %nice の意味を知った。

誤植等

  • p.68 taskset -c 0 , 4 ./sched プロセス数 1000 11000100 の間違い?
  • p.74 誤「開始から終了までの時間までの経過時間と使用時間」 正「開始から終了までの経過時間と使用時間」
  • p.82 ps -eo pid,comm,time,etime の結果が PID COMMAND ELAPSED TIME となってて、ELAPSEDTIME の順番が逆
  • p.84 sched_nice.c 誤植ではないけど、sched.c と比べて無駄に差分がある。空行の有無とか、変数宣言の位置とか、関数名とか。
  • p.98 図05-10 矢印がメチャクチャ

その他

  • やっぱりグラフ化ツールが欲しい。gnuplot か何かで作るかな…。
  • 誤植つらい。
  • しかし Linux の OOM killer の仕組みはどうにかならないんだろうか。
  • OOM killer 「やったね」って何爽やかな笑顔してんだ。「殺ったね」の間違いだろ。

f:id:tmtms:20180509221955p:plain


次回は5/23です。残念ながら私は欠席です。 会場の都合で 5/24 に変更になりました。なので私も参加します。

nseg.connpass.com

第2回「Linuxのしくみ」読書会に参加しました

4/25 に開催されたNSEGの「Linuxのしくみ」読書会の第2回に参加しました。参加者11名。第1回と同じ。

nseg.connpass.com

今回は、第3章と第4章の途中(p.65)まで読みました。

個人的な収穫

  • taskset コマンドを知った。
  • clock_gettime システムコールを知った。gettimeofday はもう古いのね…。

誤植等

  • p.45 誤「takset コマンドは」→正「taskset コマンドは」
  • p.50 誤「次のようなことがことがわかりました。」→正「次のようなことがわかりました。」
  • p.53 「sched プログラム内」の「sched」のフォントがタイプライタ体になっていない。

その他

  • UNIXシステムコールに慣れてない人はやはり fork, exec に戸惑うらしい。
  • bash 等のシェルにも exec がある。引数なしの exec の動きが引数ありの exec と全然違うけど、何故同じ名前にしたし…。
  • 音読時に sched を何と呼ぶのか問題。
  • 測定結果を簡単にグラフ化できるスクリプト等があればありがたかった。
  • VMだと結果が綺麗に出ない場合がある。
  • 誤植つらい

次回は5/9です。

nseg.connpass.com

第1回「Linuxのしくみ」読書会に参加しました

4/11 NSEGの「Linuxのしくみ」読書会の第1回に参加しました。参加者11名。だいたいいつも第1回は参加者が多いんですが、これがいつまで続くか。今回は関西方面からリモート参加の方もいました。

nseg.connpass.com

今回は「はじめに」と1章と2章を読みました。

  • @tatsushi_d の知識、マジパネェ。

  • 「Linuxのしくみ」なのにMac上で試そうとする人多すぎ。チャレンジャーすぎる。

  • sar の結果を見て、

    統計情報を採取していた 1 秒間に、CPU コア 0 上ではユーザプロセス、ここでは loop プログラムが常に動作していたことがわかります

    と書かれてた部分について、「なぜこの出力から loop プログラムだということがわかるのか」と疑問に思った人が数人いた。たしかにちょっと紛らわしい書き方かもしれない。

  • 最近の sar は色がつくのね。

  • ロケールが日本語だと sar の通常の行と最後の「平均値」の行でカラムがずれててダサい。

  • 間違いがたくさんありそうだったので電子書籍にした自分勝ち組。正誤表↓を見ると第3刷でも結構修正されそうな感じ。

docs.google.com

2章まででは、自分は特に知らないことはなかったんですが、良い本です。会社の新人教育用にも良いと思いました。

次回は 4/25 の予定です。

nseg.connpass.com

gihyo.jp の電子書籍は DRMフリーなのでおすすめです。

gihyo.jp

第10回「オブジェクト指向設計実践ガイド」読書会に参加しました

3/28 NSEGの「オブジェクト指向設計実践ガイド」読書会の第10回に参加しました。参加者4名。今回で最終回でした。

nseg.connpass.com

今回は第9章「費用対効果の高いテストを設計する」の途中から最後まで読みました。

p.277 に「witdh」というtypoあり。

抽象クラスと具象クラスで共通のテストをmoduleで実装しておいて、それぞれのクラスのテストでincludeするというのはなるほどなーって感じでした。 RSpecでも同じようなことできるんかな。

「そもそも言語として型とかインタフェースがあればこんなテストなんてしなくてもいいんじゃないの?」って意見もあり、まあそれはそうだよね。

プライベートメソッドのテストを書くかどうかというよく聞く話題についても書かれてました。「プライベートメソッドのテストを書きたくなったら別のクラスのパブリックメソッドにすればいい」というのは聞いたことあるけど、それをしていいのはインタフェースが安定している場合だけ。

新しいパブリックインターフェースの安定性(と不安定性)はもともとプライベートインターフェースであったころとまったく変わりません。場所が移動されたからといって、不思議な力でメソッドの信頼性が増すことはないのです。

Rubyの知識がちょっと必要ですが、言語的な制約がゆるいRubyを題材にすることで、Java等のオブジェクト指向言語がなぜそのような仕様/制約になっているのかを理解することができるかもしれません。

いろいろ勉強になったよい本でした。

次回からは「[試して理解]Linuxのしくみ~実験と図解で学ぶOSとハードウェアの基礎知識」を読む予定です。

[試して理解]Linuxのしくみ ~実験と図解で学ぶOSとハードウェアの基礎知識

[試して理解]Linuxのしくみ ~実験と図解で学ぶOSとハードウェアの基礎知識

第8回「オブジェクト指向設計実践ガイド」読書会に参加したけど第7回の補講をやりました

12/13 NSEGの「オブジェクト指向設計実践ガイド」読書会の第8回に参加しましたが、行ってみたら参加者3人だったので延期になりました。

が、3人とも前回欠席だったので、補講(?)として第7章を読みました。

第6章のクラスに続いて第7章はモジュールの話でした。Rubyのモジュールには色んな用途がありますが、ここでは mix-in としての用途の話です。

オブジェクトのメソッドについて、

探索は階層構造の頂点へとスーパークラスを 1 つ 1 つさかのぼっていき、最終的に Object クラスを探索します。そこでもメソッドが見つからなかった場合、つまり適切なメソッドを見つける試みがすべて失敗に終わった場合は、そこで探索が終わると思うかもしれません。しかし多くの言語には、メッセージを解決するための第二の方法が備わっています。

として、Ruby の method_missing メソッドが説明されてたけど、Ruby以外の「多くの言語」には何があるんだろう…。Java や Python にも Ruby の method_missing 相当のものがあるんだろうか。

[追記] Python でも似たようなことはできるらしい。

全般的に書いてあることは納得できるし、Ruby でプログラムを作る場合には気にした方がいいことだとは思ったのですが、実は Ruby のようなかなり自由な言語じゃなければ、言語仕様レベルで強制されて気にしなくてもそれなりにちゃんとした設計になるんじゃないかとも思ったり…。


延期になった第8回は 12/27 です。もしかしたら終わったあとに軽く忘年会風のことをやるかもしれません。

nseg.connpass.com

第6回「オブジェクト指向設計実践ガイド」読書会に参加しました

11/15 NSEGの「オブジェクト指向設計実践ガイド」読書会の第6回に参加しました。参加者3名でした。寂しい。

nseg.connpass.com

今回は第6章を読みました。

第6章は継承の話でした。

普段あんまり意識せずになんとなく実装していたのですが、明文化されるとなるほどなーと。

継承関係にあるクラス間であっても、オブジェクト間と同様に依存を少なくすべきという感じの話でした。

super を使うのではなく、親クラスからサブクラスのメソッドを呼ぶようにするというのは、たしかに良いかもしれないけど、post_initialize メソッドを作るってのはどうかなぁ。個人的には initialize メソッドについては super 使ってもいいと思いました。

あとは、Rubyではsupersuper()の括弧の有無で振る舞いが変わるというような話もしました。

第5回「オブジェクト指向設計実践ガイド」読書会に参加しました

11/1 NSEGの「オブジェクト指向設計実践ガイド」読書会の第5回に参加しました。参加者7名でした。

nseg.connpass.com

今回は第5章を読みました。

オブジェクトの型(クラス)を調べて処理を変えるというコードの例としてcase文が使われてました:

case preparer
when Mechanic
  preparer.prepare_bicycles(bicycles)
when TripCoordinator
  preparer.buy_food(customers)
when Driver
  preparer.gas_up(vehicle)
  preparer.fill_water_tank(vehicle)
end

本に何の説明も書かれてなかったのでRubyを知らない人は、このようにcase文でクラスの判定ができるということがわからなかったようです。

Rubyのcase文は単純な一致比較だけでなく、文字列が正規表現に適合するかとか、上の例のようにクラスのオブジェクトかどうかを調べたり、when に書かれたオブジェクトによって色んな比較が便利にできるのですが、その仕組みは単純で、

case a
when b
  ...

は、b === a を判定しているにすぎません。

基底クラスであるObjectの === メソッドは単純一致比較、正規表現の === メソッドは正規表現に適合するかどうかの比較、Classの === メソッドはオブジェクトがクラスインスタンスかどうかの比較というように、各オブジェクトに適切な === メソッドを定義することで自然にcase文が記述できるようになっているのです。

まさにこの章の本題である「抽象的なパブリックインタフェースを取り決める」ということが実装されている例になってますね。

後半、静的型付けと動的型付けの比較をしていますが、静的型付けのメリットを過小評価してるような気がしました。 コンパイル時の型検査を "コストが高い割にわずかな価値しか得られない深刻な制約" と書いていたり。

本の中で静的型付けのメリットとして挙げられてますが、

  • コンパイラがコンパイル時に型エラーを発見してくれる
  • 可視化された型情報は、文書の役割も果たしてくれる

この2つはかなり役に立つと個人的には思ってます。 1番目は自分がコードを書く時。2番目は人のコードを読む時。

そういや、Ruby にもバージョン3で(どんな形かはわかりませんが)型システムが入るらしいですね。

今はまた静的型付き言語が流行ってきてるようですが、原著「Practical Object-Oriented Design in Ruby」は2012年なのでちょっと古いのかもしれません。 来年に第二版が出るみたいですね。

Practical Object-Oriented Design in Ruby: An Agile Primer (2nd Edition)

Practical Object-Oriented Design in Ruby: An Agile Primer (2nd Edition)


次回は 11/15 です。

nseg.connpass.com

ところで12/2に「ながのRubyの会」があるのでよろしければこちらもご参加ください。

naruby.connpass.com

第3回「オブジェクト指向設計実践ガイド」読書会に参加しました

10/4 NSEGの「オブジェクト指向設計実践ガイド」読書会の第3回に参加しました。参加者11名でした。盛況ですね。

nseg.connpass.com

今回は第3章を読みました。

コード例が単順すぎて、より良い設計として挙げられてるコードがいまいちピンとこないところもありましたが、なんとなくわかった気がします。

「自身より変更されないものに依存しなさい」は、なるほどなーと思いました。

引数を一つのHashで受けつけるというのは、訳注にもありましたが今はキーワード引数を使うのが良いですね。

本の「はじめに」に「本で説明する概念を理解するために Ruby を知っている必要はありません」とありましたが、コード例を読み解くにはやっぱりRubyの知識が必要です。Rubyの構文についての説明が一切ないので。

私は前回の第2章には不参加だったのですが、attr_reader とか @変数 とかが何の説明もなしに出てきてもRubyを知らない人は戸惑いますよね。

p.50 の

Wheel = Struct.new(:rim, :tire)
def wheelify(data)
  data.collect {|cell|
    Wheel.new(cell[0], cell[1])}
end

Struct を使うのは無駄に難易度を上げているんじゃないかと思いました。

第3章には module が出てきたので、名前空間を分けるためのもの…と説明しました。

読み終わった後で、モジュールとクラスについて以下の説明をしました。あんまり本書の内容とは関係ありませんが。

Rubyはクラスもオブジェクトで、Classクラスのインスタンス。

123.class   #=> Integer
"abc".class #=> String
String.class  #=> Class
class Hoge
end

Hoge = Class.new

と同じ。

モジュールはクラスと似たようなものだけど、インスタンスを生成することはできない。 Module クラスを継承してインスタンスを作る機能を追加したものが Class クラス。

Class.superclass #=> Module

Class.new で作った直後のクラスは名前がない。定数に代入することでクラス名がつけられる。

a = Class.new  #=> #<Class:0x0055ed560694f8>
X = a          #=> X
a              #=> X

2章の例は Struct.new で名無しクラスを作って、Wheel に代入することで Wheel クラスを作っている。

説明したことで、なんかRubyは難しいと思われてしまった感がなきにしもあらずですが、Rubyは難しくないですよ!こわくないよー。


次回は 10/18 です。

nseg.connpass.com

この書籍(に限らず技術評論社の書籍全般)を電子書籍で購入する場合は https://gihyo.jp/dp がおすすめです。 ひとつ購入すればPDFとEPUBの両方が入手できて、DRMフリーです。

gihyo.jp

NSEG #92

9/16 NSEG #92 に参加しました。参加者9人でした。

アベさんが「kotlin Null Safety」という発表をしました。

Kotlinでぬるぽを発生させる方法あれこれの紹介でした(?)。

http://rayflood.org/diary-temp/nseg92.html

それ以外はネタが無かったので、「横浜へなちょこプログラミング勉強会」の「オフラインリアルタイムどう書く」の過去問をパクってみんなでやりました。

「どう書く」はたしかRubyKaigi 2016の懇親会で聞いたと思うのですが、面白そうだから機会があればやりたいと思ってました。

Tick-Tack-Toe 〜 横へな 2012.7.6 を2時間くらいでもくもくと作り、その後各自書いたプログラムを披露するって感じで。

私は最初Rubyで書いて、その後Cで書き直しました。Cをかなり忘れててやばかったです。

# http://nabetani.sakura.ne.jp/hena/1/

@board = []  # インデックスがマスの位置(1はじまり)、値がプレイヤー名 'o' or 'x'

def next_player
  @player == 'o' ? 'x' : 'o'
end

def judge
  [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
    [1, 4, 7],
    [2, 5, 8],
    [3, 6, 9],
    [1, 5, 9],
    [3, 5, 7],
  ].each do |i, j, k|
    if @board[i] && @board[i] == @board[j] && @board[j] == @board[k]
      return "#{@board[i]} won."
    end
  end
  nil
end

def ttt(input)
  @board.clear
  @player = 'o'
  turn = 1
  input.each_char do |c|
    break if turn > 9
    i = c.to_i
    return "Foul : #{next_player} won." if @board[i]
    @board[i] = @player
    if result = judge
      return result
    end
    @player = next_player
    turn += 1
  end
  return 'Draw game.'
end

data = <<EOS
79538246      x won.
35497162193       x won.
61978543      x won.
254961323121      x won.
6134278187        x won.
4319581           Foul : x won.
9625663381        Foul : x won.
7975662           Foul : x won.
2368799597        Foul : x won.
18652368566       Foul : x won.
965715            o won.
38745796      o won.
371929            o won.
758698769     o won.
42683953      o won.
618843927     Foul : o won.
36535224      Foul : o won.
882973            Foul : o won.
653675681     Foul : o won.
9729934662        Foul : o won.
972651483927      Draw game.
5439126787        Draw game.
142583697     Draw game.
42198637563       Draw game.
657391482     Draw game.
EOS

data.each_line do |line|
  input, output = line.chomp.split(/\t+/)
  res = ttt(input)
  unless res == output
    puts "ttt(#{input}) returned #{res.inspect} but expected #{output.inspect}"
  end
end
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char player = 'o';
char board[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

char next_player()
{
  return player == 'o' ? 'x' : 'o';
}

char judge()
{
  int cond[][3] = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9},
    {1, 4, 7},
    {2, 5, 8},
    {3, 6, 9},
    {1, 5, 9},
    {3, 5, 7},
  };
  for (int l = 0; l < sizeof(cond)/sizeof(cond[0]); l++) {
    int i = cond[l][0];
    int j = cond[l][1];
    int k = cond[l][2];
    if (board[i] && board[i] == board[j] && board[j] == board[k])
      return board[i];
  }
  return 0;
}

int main(int argc, char *argv[])
{
  int turn = 1;
  for (int i = 0; i < strlen(argv[1]); i++) {
    char c = argv[1][i];
    if (turn > 9)
      break;
    int x = c - '0';
    if (board[x]) {
      printf("Foul : %c won.\n", next_player());
      return 0;
    }
    board[x] = player;
    char winner = judge();
    if (winner) {
      printf("%c won.\n", winner);
      return 0;
    }
    player = next_player();
    turn += 1;
  }
  puts("Draw game.");
  return 0;
}

第1回「オブジェクト指向設計実践ガイド」読書会に参加しました

9/6 NSEGの「オブジェクト指向設計実践ガイド」読書会の第1回に参加しました。参加者8名でした。

nseg.connpass.com

第1章は導入部って感じで具体的なことはあまり書かれていなかったのですが、胃が痛くなるようないい話が満載でした。

設計がないと、管理されていない依存関係が大混乱を引き起こします。

単純であるべき変更がアプリケーション内部を次々と伝わり、あらゆるところでコードを破壊するのです。そして、広範囲の書き直しが必要になります。テストは四方から板挟みになり、やがて開発を助けてくれるというよりも、開発を妨げているように感じてくるでしょう。

うう…あるあるだ…。

アプリケーションはどれもがコードの集まりです。つまり、コードの構成こそが「設計」であると言えます。

設計とは、同じように訓練された作業員が同一の製品をつくる組み立てラインではなく、アトリエなのです。 志を同じくした芸術家たちが、特別なアプリケーションを創り上げる仕事場です。ですから、設計は芸術と言えます。コード構成の芸術なのです。

動かせるソフトウェアに先立って全体の設計をつくったところで、それが正しいことはありません。それがどんなものであってもです。ですから、仕様どおりにアプリケーションを書いたところで、顧客のニーズを満たすアプリケーションができないことは決まりきっています

もう、すごい当たり前のことなんだけど、プログラマーな人以外はわかってくれなそう。

同じことを何度も繰り返しながら異なる結果を期待することが狂気であるならば、アジャイル宣言によって、私たちは全体として正気を取り戻しました。アジャイルが有効である理由は、ソフトウェアがかたちになる「前」に確かさを手に入れることはできないと認めたからです。

認めてほしい…。

その昔、プログラマーは生産したコードの行数で判断されることもありました。このメトリクスが導入された経緯は明らかでしょう。プログラミングを、同じように訓練された作業員がまったく同じ製品を組み立てる工程だと考えている上司がいたとします。その人たちが、個々の生産性はそれぞれの成果物の量で単純に測れると思い込むのは容易にあり得ることです。

その昔じゃなくて今でも普通にありそう。


というわけで第2章以降も期待です。

次回は9/20です(私はRubyKaigiのために欠席ですが…)。

nseg.connpass.com

この書籍(に限らず技術評論社の書籍全般)を電子書籍で購入する場合は https://gihyo.jp/dp がおすすめです。 ひとつ購入すればPDFとEPUBの両方が入手できて、DRMフリーです。

gihyo.jp

もちろんAmazon Kindle版もあります。

amzn.to