« 2007年5月 | トップページ | 2007年8月 »

2007年6月

2007/06/16

【Ruby関西】RubyプログラムからJavaの匂いを消したい

 第16回 Ruby関西に行ってきた。
 Ruby会議2007の話もあり、牛尾さんも来られて、いつもの如く盛り上がった。
 楽しかったことをメモ。

【1】Continuation(継続)ライブラリは恐ろしい~yharaさんの話

 Continuation(継続)は、C 言語の setjmp()/longjmp() に相当するRubyのライブラリのこと。
 定義は下記に書かれている。

組み込み関数 callcc

 何故こんなライブラリが必要なのか?
 理由は、込み入ったループ処理でジャンプしたい時、イベント処理で複雑にwaitしている時にジャンプしたい時があるから。

 普通は、使わなくても書けるし、多分書かない方がいい。
 yharaさんが機能を解説してくれたが、callccが入ると、セーブポイントへジャンプするため、同じようなステートメントを何度も通過するので、机上デバッグできない。

 でも、こんな問題でcallccを使うと綺麗に解ける。(元々はSCIP本にあるらしい)

Baker, Cooper, Fletcher, MillerとSmithは五階建てアパートの異なる階に住んでいる。
Bakerは最上階に住むのではない。
Cooperは最下階に住むのではない。
Fletcherは最上階にも最下階にも住むのではない。
MillerはCooperより上の階に住んでいる。
SmithはFletcherの隣の階に住むのではない。
FletcherはCooperの隣の階に住むのではない。
それぞれはどの階に住んでいるか。

Rubyで書くとこうなる。

[Haskell] 非決定性計算

require "amb"

A = Amb.new

baker = A.choose(1, 2, 3, 4, 5)
cooper = A.choose(1, 2, 3, 4, 5)
fletcher = A.choose(1, 2, 3, 4, 5)
miller = A.choose(1, 2, 3, 4, 5)
smith = A.choose(1, 2, 3, 4, 5)

A.assert([baker, cooper, fletcher, miller, smith].uniq.length == 5)
A.assert(baker != 5)
A.assert(cooper != 1)
A.assert(fletcher != 1 && fletcher != 5)
A.assert(miller > cooper)
A.assert((smith - fletcher).abs != 1)
A.assert((fletcher - cooper).abs != 1)

p [baker, cooper, fletcher, miller, smith]

 amb.choose()にはcallccが使われているとのこと。
 Howではなくwhatを書くだけで解けてしまっている。
 うーん、すごすぎ。

 ちなみにHaskellではこう書けるらしい。

リストモナドで非決定性計算

import Control.Monad.List

solve = do baker <- [1, 2, 3, 4, 5]
cooper <- [1, 2, 3, 4, 5]
fletcher <- [1, 2, 3, 4, 5]
miller <- [1, 2, 3, 4, 5]
smith <- [1, 2, 3, 4, 5]
guard $ distinct [baker, cooper, fletcher, miller, smith]
guard $ baker /= 5
guard $ cooper /= 1
guard $ fletcher /= 1 && fletcher /= 5
guard $ miller > cooper
guard $ abs (smith - fletcher) /= 1
guard $ abs (fletcher - cooper) /= 1
[baker, cooper, fletcher, miller, smith]

distinct :: Eq a => [a] -> Bool
distinct [] = True
distinct (x:xs) = all (/=x) xs && distinct xs

main :: IO()
main = print solve

(解答)[3,2,4,5,1]

【2】自分が書いたRubyプログラムからJavaの匂いを消したい~(余談)牛尾さんの話

 牛尾さんが来られていたので、ちょっとだけ話が出来た。
 今はJavaよりもRubyにはまっているとのこと。
 型を書くのが面倒になってきた、RailsのActiveRecordはJavaのDAOと比較にならないほど使いやすい、と言っていた。
 
 懇親会で、牛尾さんが自作のRubyプログラムをRuby関西のRubyistに添削してもらっていた\(^o^)/
 Rubyistに話を聞いたら、牛尾さんのプログラムはクラス継承もあって設計がすごくキッチリしている。
 でも、Javaの人が書いたとすぐに分かるプログラムで、RubyならIF文の羅列やbooleanメソッドなどはもっと短く書けるよ、とのこと。

 牛尾さんに後で話を聞いたら、プログラムからJavaの匂いを消したいんですよ、Rubyを体に染み込ませるまで書き込みたい、とのこと。
 モデリングのプロである彼がそこまではまっているとは思ってもみなかった。
 eXtreme Programming以来の衝撃がRubyにあるんですよ、と言う彼の言葉が印象的だった。

 うじひささんが、牛尾さんのことをアジャイル王子(XP祭り関西2006のライブセッションの王子役)と言っていたのも印象に残った。
 XP祭り関西を未だに思い出として残している人たちがいる。

 とまあ、技術の話も懇親会も楽しかった。


| | コメント (0) | トラックバック (0)

2007/06/15

【Perl関西】Perlベストプラクティス~プログラミング作法は何故必要か?

 昨夜、kansai.pmのPerlベストプラクティス勉強会#2(略してPBP)に参加してきた。
 勉強会の内容は、エクストリームリーディング方式で「Perlベストプラクティス」を読む読書会。
 るびま勉強会と違って、物静かだが、コアな議論ができた。

【1】Perltidyrc~Perlベストプラクティスに従ったPerlプログラムのCheckStyle

 コーディング流派の多いPerlは、どうしても、ソースの可読性が低くなりがち。
 例えば、Perlの場合、$変数がスカラー変数なのか、参照変数なのか、が分からなくなる時がある。
 だから、変数名に「ref_」「_ref」を付けるやり方があるらしい。

 話を聞いたら、Perlベストプラクティスの本がPerlのプログラミング作法らしい。

 そのためのチェックツール「Perltidyrc」があるらしく、それを使うと、Perlベストプラクティスの本の何頁と相違しているから警告メッセージが出た、ということができるらしい。
 但し、英語の本らしいけれど。
 すごすぎ~。

【2】何故、プログラミング作法は必要なのか?~JavaでもRubyでもPerlでも同じ

 インデントや変数名のネーミングルール、1ステートメントの改行などの細かなルールがPerlベストプラクティスにある。
 何故そこまでこだわるのか?
 
 答えは、プログラムの可読性を高めたいから。
 その理由は、運用保守フェーズで、プログラムの可読性が保守性と密接に関わっているから。
 
 だが、ラフにプログラムを書きたい時がある。
 パッと思いついたアイデアを書き込んで動かしてみたい時、コーディングルールや整合性にあまりこだわらずにサクッと書きたい時がある。
 そして、実際に動かしながら、書いたプログラムのロジックの整合性を突き詰めながら、自分のアイデアを確かめていく。
 そんな時に、パッと思いついたプログラムは、上級者になるほど読みやすい構造になっている時が多い。

 いのうえさんが「7年経ってようやく長い変数名が自然に出てくるようになりました」と言っていたのが印象的だった。
 プログラムを書く手が自然にプログラミング作法に則っているのが上級者。
 スパゲティのようなプログラム、手が全く動かず空白の多いプログラムが多いのが初心者。

 個人的には、モデリング作業がプログラミングと同じ感覚で、簡単に動作確認できて、モデルの整合性をチェックできるようになれたらいいのに、と思う。

| | コメント (0) | トラックバック (0)

2007/06/09

マネージャの仕事はビフォーアフター志向

 最近、こんな本「プロフェッショナルマネジャーになる50の技法」を読んでみて、「マネージャの仕事とは一体何だろう?」と疑問に思った。
 自分が経験したことを振り返りながら、気付いたことを書いてみる。

【1】現場を変化させたことが評価基準になる~ビフォーアフター志向

 以前、日曜夜8時に住宅リフォームの番組があって、僕も楽しく見ていた。
 内容は、猫の背中ほどの中古住宅をいかに安い資金で、あっと驚くようなお洒落ですみやすい家へリフォームするか、というもの。
 リフォーム前と後の変化が大きい時ほど面白い。
 同様に、スタイルに自信の無い女性を美のスペシャリストが大変身させるという番組もあった。
 いずれも、「関与する前と後でいかに変化させたか」が成功の評価のポイントになる。

 山田太郎さん(ネクステック社長)の外資系プロマネ成功術の一つに「客を変化させたことが評価になる」というフレーズがあるけれど、それと同じ。

 「マネージャの仕事はビフォーアフター志向」という文句が最初に出てくるが、実体験上その通りだと思う。
 
【2】現場の開発者を成長させることでプロジェクトを加速させる

 プロジェクトを回しながら、開発チームを動かす場合の「ビフォーアフター志向」とは何か?
 それは「現場の開発者を成長させたこと」だと思う。
 例えば、最初は、1画面の実装に1週間もかかっていたのに、3ヵ月後にはわずか2人日で検証完了できるようになるとか。
 つまり、開発速度がスピードアップしなければ、成長したことにはならない。
 
 マネージャも、成長による加速度を工数計算に入れている節がある。
 つまり、そのシステムの仕様やフレームワーク・ライブラリを3ヶ月も使えば、ある程度慣れてくるだろうから、最初の頃よりも高品質で少ない工数で開発できるでしょ、と。
 実際はそう思惑通りにならないけど。。

 ある1人の開発者が成長することで、周囲のベテランも刺激を受ける。
 成長する開発者がいる現場は、活気があって自然に楽しい。
 その意味では、開発チームは、色んなスキルを持つ人たちが集まっている方が、成長しやすいのびしろが残っている。
 だから、若手を故意にチームに入れて、彼を育てることがすごくマネージャには重要。

 プロジェクトマネージャは、「いかに開発者を成長させるか?」「成長できる開発環境をいかに作るか?」を常に考えて準備しておくべきだと思う。
 この辺りの技術は、プロジェクトファシリテーションやXP(eXtremre Programming)がすごく意識してルール化しているので参考になる。

 開発者を成長させるには、ペアプロは効果的。
 綺麗なプログラムやロジックを読んで真似て書くことで、その考え方に慣れていく。

【3】変化を作る仕掛け~特に報連相

 マネージャとしては、チームを変化させる手段の一つに、報連相の仕組みを作ることがある。
 つまり、報告の業務フローを明示すること。
 昨日は何をやったか、今日は何をするのか、を毎日報告させるだけで、開発者にマネージャの意図を意識付けることができる。
 実際、報告の時に、遅れた原因を聞いてアドバイスしたり、彼の能力ではこのプログラムは書けそうに無いと分かったら、アサインし直すと決断することができる。
 プロジェクトファシリテーションでは、朝会をうまく進捗報告の場としてルール化している。

 以前、児玉公信さんの講演で「エリクソンペンカーのプロセス図を若手経営者に書かせたら、フィードバックループが無い」と嘆いていたのを思い出す。
 つまり、結果を評価するというPDCAサイクルを意識する人が少なかったという意味。
 報告とは、開発者の今日の作業を計画し、昨日の彼の作業を評価するという大事な場でもある。

 マネージャとしては、開発者からの相談はいつも受け入れるようにしている。
 理由は、開発者の作業を止めないようにしたいだけでなく、彼の作業ステータスを確認したり、彼が今の作業をどれくらい理解しているのかを把握するのに使えるから。
 数時間おきに相談に来る場合、その相談内容で、彼の進捗がはかどっているかを簡単に把握できる。
 また、彼がどの程度まで自力で解決したか、という点から、彼の能力を評価する尺度になる。

 プロジェクトファシリテーションは、相談しやすい雰囲気作りをテクニック化してツール化している。

 プロジェクトファシリテーション、XPではこの仕掛けをチームの中から作り出すように意図している。
 チームビルディングがうまいと思う。

【4】マネージャの仕事とは?

 マネージャの仕事は、開発者の仕事とは違う。
 開発者は1人分だけの仕事をやればいい。
 でも、マネージャになると、自分一人の仕事はもちろん、部下5人の仕事もカバーできるだけの能力も必須。
 更にその上で、チームを回す技術が必要。

 この辺りの技術を再考してみたい。

| | コメント (0) | トラックバック (0)

2007/06/08

Eclipseリファクタリング・メモ

 Eclipseの使い方を一覧で分かりやすく説明しているHPがあったので、メモ。
 特にリファクタリングの手順が分かりやすい。

Eclipseリファクタリング

 Eclipseのリファクタリングは非常に使いやすいのに、何故か皆、使ってない。
 ファウラーのリファクタリング本を読んでないのだろうか?
 Javaプログラマにとって、綺麗なプログラムを書くための技術が全て詰まっている良書なのに。

【リファクタリングの目的】

 最近、ソースインスペクションをする立場になってみて、仕様を理解せずに長々と書いている下品なプログラムを見ると、すぐにカチンと来てしまう(-_-;)

 Fatなメソッド、Fatなクラスは、不吉な匂いがする。
 女性と(だけじゃなくて男性も)同じく、太ったクラスはダイエットすべき。
 
 リファクタリングする真の目的は、誰でも理解できるプログラムにして保守性を高めることにある。
 特に、プログラマは派遣契約が多いため、書き散らしたプログラムは3ヵ月後には作者不明のソースになってしまい、下手なソースは誰も修正できなくなる。
 そうならないように、誰でもプログラムの意図をすぐに理解できて保守性を高めることは、運用保守フェーズで大きな影響を持つ。

【リファクタリングすべき箇所】
 ペアプロしながら、下記の点に注意してリファクタリングする時が多い。

■スペルミスや分かりにくいメソッド名や変数名
 → すぐに「名前変更」 (皆、英語は弱い(-_-;))

■一塊の機能を見つけたら → 「メソッド抽出」
 → 他クラスへ「移動」することが多い

■意味不明な定数を見つけたら
 → 「定数の抽出」

■無駄に長いgetter処理、ループ処理で何度も使われるローカル変数
 → 「ローカル変数の抽出」
 → ここから、メソッドの抽出をやって、引数の依存関係を減らす

■クラス内で何度も使われて、状態として保持した方が良い変数
 → 「フィールドのカプセル化 」

■ローカル変数をプログラムへ戻す
 → 「インライン化 」

■メソッド名の引数が、intやStringのようなプリミティブな型ばかりでやたらと長い
 → 引数の中で関係あるものをクラスとして抽出し、「メソッドシグニチャの変更」で引数を減らす

■継承構造を作りたい
 → 「インターフェイスの抽出」
 → インターフェイス、抽象クラスを作り、具象サブクラスを作る

■2つのサブクラスに似たような処理があって共通化したい時
 → 「プルアップ」
■プルアップの逆操作
 → 「プッシュダウン」

 プルアップって皆知らないみたい。
 機能を共通化したい時の手法は、下記2種類しかない。

○サブルーチン呼び出し(いわゆるファンクションコール)
○継承を使って親クラスに共通ルーチンを持たせる(いわゆる実装継承)

 オブジェクト指向に慣れていない人は、継承構造を使うプログラミングが苦手みたい。

 以前、るびま勉強会でRubyistと継承関係について議論したら、Rubyistは継承を殆ど使わず、特異メソッドやMixinで代用するらしい。
 Javaプログラマとしては、上記2種類を意識して使い分けることが多いから、ちょっと違和感あり。

■サブクラスを動的に使い分けて生成したい
 → 「ファクトリーの導入」

 サブクラスを使って処理を使い分けている時、必ずIF文、case文がある。
 その部分をファクトリーメソッドで置き換えて、外から来るフラグに応じて、生成する具象クラスを切り替える。

 オブジェクト指向に慣れていない人は、インターフェイスだけで書かれたプログラムが今どんなロジックを通過しているのか、を理解できない時が多い。
 だから、デバッグしても、今どのインスタンスで実行されているのか、という観点が無い。

【番外編~Rubyの場合は??】

 Rubyでも最近いい本「Rubyist Magazine出張版正しいRubyコードの―RubyistのRubyistによる、Rubyistとそうでない人のための」が出た。
 るびま勉強会(関西)でも読んでます。


 
 Rubyistによると「ファウラーの本よりも初心者向けだがいい本ですよ」とのこと。
 中身を読んでみると、Rubyのリファクタリング版という感触だった。

 Java屋さんとRuby屋さんにとって、こういうリファクタリング本は、プログラミング技術を上げてくれる良書。
 もう一度読み直してみようと思う。

| | コメント (0) | トラックバック (0)

2007/06/05

開発プロセスを設計するという発想

 最近興味があること。
 それは、「開発プロセスを自由自在に設計して、運営できるか?」ということ。
 こんな本「SEの仕事を楽しくしよう」を読んでみて、色々と考えさせられる所があった。

 RUP、XP、CMM/CMMI、ソフトウェアプロダクトラインなどを聞きかじって、自分で少しだけ試してみた経験を振り返ってみて、考察してみる。

【1】新規開発と派生開発~IT業界特有の開発プロセス

 開発プロセスを勉強すると必ず「ウォーターフォール型開発よりもインクリメンタル型開発の方がいい」という文句に良く出る。
 でも、実際の現場では、ウォーターフォール型開発でもインクリメンタル型開発でも、プロジェクトを制御できていない。
 その原因は、2種類の開発プロセスがある事実を知らないことにあると思う。

 最初からスクラッチ開発する時は、小さなサイクルでウォーターフォール型開発を行う時が多い。
 最近なら、オブジェクト指向言語で作るから、オブジェクト指向開発のMAX版であるRUPをカスタマイズして開発することが多い。

 しかし、リリース後、運用保守フェーズに入ると、現実に動いているシステムに機能追加して、デグレが起きないように開発しなくてはならない。
 この時に、開発プロセスをコントロールできない時が多い。

 この本「SEの仕事を楽しくしよう」では、この時の開発プロセスを「派生開発」と呼んでいる。
 つまり、実際のプログラムから設計書をリバースして作って、機能設計するプロセスになる。
 これは、RUPやウォーターフォール型開発のような、要件定義から設計してプログラミングするというプロセスと大きく異なる。
 上からの開発ではなく、下から開発していくスタイル。
 この開発スタイルを意識しているのが、XP(eXtreme Programming)だと思う。

 XPの場合、動いているプログラムがまさに正。
 設計書は不要で、インテグレーション重視。
 小さなイテレーションで開発しながら、機能追加していく。

 SEは、従来の上からの新規開発と、運用保守フェーズで使われる下からの派生開発の2種類を自由自在に操る必要がある。

【2】肝は構成管理~プログラミングよりもビルド作業が重要

 CVSやSubversionへCIする時のコミットログを重視しないプロジェクトが多くて、僕は不満。
 コミットログは、ソース変更の意図を現した重要なログ。
 コミットログをうまく使えば、要件管理や不具合修正、機能追加の作業ステータスを確実にトレースできる。
 これは構成管理の一つに使えると思う。

 CMM/CMMIやソフトウェアプロダクトラインでは、構成管理を重視している。
 ビルド作業では、リビジョン番号を付けたモジュールを作って、リリースする。
 
 この作業を、現場のプロジェクトでは意外と意識していない。
 実際の現場では、本番リリースのモジュールと開発途中のモジュールを意識して使い分けるやり方が浸透していない気がする。
 だから、モジュールのデグレなど、品質管理が甘いように思う。

 構成管理は、開発プロセスを制御する時の肝になる技術。
 「いつまでに、どんな機能をリリースするか?」を制御する時に、必要な技術が構成管理に全て含まれている。

【3】肝は、変化を受け入れること

 「仕様変更が多くて、いつまでもプロジェクトが収束しない」という不満は良く聞く。
 その原因の殆どは、顧客の要望をSIerがコントロールできていないというマネジメントにあると思うが、技術が不足しているのも一つの原因だと思う。
 つまり、度重なる仕様変更に耐えれる技術力や運用を開発チームが持っているか?

 XP(eXtreme Programming)では、「変化を抱擁する」と言って、これを意識して使っている。
 完璧な要件定義ができないのなら、仕様変更に対し、すぐに機能追加してリリースできる技術力を持とう、と。

 そのためには、モジュールの設計が保守に強いこと、リファクタリングの技術を持っていること、テストユニットを使っていつでも回帰テストで品質を確認できること、などの技術力がいる。
 XP(eXtreme Programming)はこの辺りの技術を意識している。

 実際の現場では、仕様変更に対する準備が不足している。マネージャはその意識が少ない。
 リスク管理の一つとして、自分の中で対策を持っておくべきもの。

【4】開発プロセスもプログラミングと同じ構造を持っている

 開発プロセスをアクティビティ図で書いてみると、プログラミングと同じ構造を持っていることに気付く。

・プロセスにもプログラムと同じように条件分岐や繰り返し処理があり、作業の順序がある。

・プロセスには首尾一貫性が大事。
 つまり、InputとOutputの間を論理的に説明できるか。
 これは、プログラミングでwhatを考えているのと同じ。

・アーキテクト(又はSE)とはプロセスを自由自在に設計する人であり、技術者というよりも、色んな利害関係者へシステムを説明する人であり、他者と調整する人である。

 そんなことを考えると、アーキテクト(又はSE)とは、色んな利害関係者へシステムの説明責任を負う人である、と定義できる。
 だからこそ、政治力も必要になってくる。

 開発プロセスを設計することは、プログラミング技術と同じだ、と考えた方がすっきりする時があるし、その考えで一つのモデルを作ることも可能ではなかろうか? 

| | コメント (0) | トラックバック (1)

2007/06/02

Erlang勉強会#1

Erlang勉強会#1へ行ってきた。
その時のメモ。

【1】Erlangとは?

 ErlangのWikipediaには次の説明がある。

Erlang(アーラン) は、コンピュータにおいて汎用的な用途に使うことができる並列処理指向のプログラミング言語および実行環境である。 Erlangの直列処理のサブセットの言語は、関数型言語であり、先行評価を行い、変数への代入は1回限りであり、動的型付けである。 Erlangはエリクソン社により次の条件のシステムを構築できるよう設計された。

分散化された環境
障害に耐性をもつ (フォルトトレラント)
ある程度のリアルタイム性を備える
無停止で稼働する

 最近、静かに流行している言語。

【2】開発環境のインストールとサンプルソース実行

 ここのBlogに詳しい。
 「Erlang (BEAM) emulator」を起動できれば成功。
 Rubyのirbに似ている。

 参考書は、英語の本がある。
 そこから、日本語のベータ版がPDFで落とせるらしい。

 その日本語のPDFの内容が素晴らしい!
 関数型言語、論理型言語の意味がようやく分かったような気がする。 

 サンプルソースとして「ピタゴラス数を計算する」を実行してみた。

-module(pythag).
-export([pythag/1]).

%% ピタゴラス数を計算する

pythag(N) ->
[{A,B,C} ||
A <- lists:seq(1,N),
B <- lists:seq(1,N),
C <- lists:seq(1,N),
A+B+C =< N,
A A*A+B*B =:= C*C
].

 実行ログは下記の通り。

c(pythag).
pythag:pythag(16).

[{3,4,5}]

 ソースを見て分かるように、「何がしたいか?」を書くだけで「どのように書くか?」は気にしない。

【3】「=」は代入演算子ではなく、パターンマッチング(評価する)

 関数型言語では、単一代入変数という言葉が良く出る。
 つまり、変数は1回しか代入できない。

 そして、「=」は代入演算子ではなく、パターンマッチング。
 この点が、CやJavaなどの手続き型言語に慣れた僕たちを戸惑わせる。

 つまり、LHS=RHSとは、「右辺値を評価して、その結果を左辺値のパターンにマッチさせる」。
 これは、評価しているのと同じ。
 実際に実行してみる。

X=(2+4).
X=6.
→正常

X=10.
→エラー

Y=6.
X=Y.
→正常

 「=」は評価しているということ。
 Xへ1回目に代入する時は、必ず真。
 2回目に代入する時は、値が同じ場合のみ、成功する。

 この事実は、変数Xがプログラミング言語の変数ではなく、数学で使う変数に似ている。
 つまり、X=X+1が使えない!!

 パターンマッチングの概念は、関数型言語だけでなく、Perlにも出てくる。
 この発想があるからこそ、正規表現が使える。

 色んな言語を知ることは、「現実をモデル化する技術」を一つ増やしてくれる。
 それが楽しい。

| | コメント (0) | トラックバック (0)

« 2007年5月 | トップページ | 2007年8月 »