ラベル 技術論 の投稿を表示しています。 すべての投稿を表示
ラベル 技術論 の投稿を表示しています。 すべての投稿を表示

2014年8月20日水曜日

プログラミングにおける「コメント」を軽視してないか

「他人が書いたプログラムの解読」は、ソフトウェアエンジニアにとってもっとも厄介な仕事の一つでありながら、必ず求められる作業です。

他人が書いたプログラムとの格闘戦は、ソフトウェアエンジニアの方なら経験がおありだと思います。もしかしたらそれが日常かもしれません。

逆にプログラムを白紙の状態から書いていく機会というのは、新規のソフトウェア製品や新規サービスの開発に初期メンバーとして参画するといったものがあります。しかしソフトウェアエンジニアの仕事としては、それよりも既存の製品や既存のサービスに機能を追加したり不具合を修正するなど、すでに存在するプログラムに手を加える機会も多いです。むしろこちらの方が多いかもしれません。だから、すでに存在する他人が書いたプログラムを解読する必要が出てくるわけですね。

そもそも、なぜ他人が書いたプログラムの解読が難しいのかといえば、プログラムに書かれる情報はあくまでプログラム上の処理の流れを記述してあるのであって、その処理の目的や背景、その処理を行う理由といった、いわば"プログラムの文脈"に関する情報は含まないからです。

だから、プログラムの処理自体が完全に理解できたとしても、それがどういう目的で何を達成するための処理なのか、全体の中で果たす役割は何なのかさっぱり分からない、という事態もありえます。

そこで大きな役割を果たすのが、ソースコードに挿入するコメントであると考えます。コメントが書いてあることによって、"プログラムの文脈"に関する情報を得ることができれば、プログラムへの理解は飛躍的に速くなります。

一方、プログラミングにおいて、コメントは極力少なくすべきであるという主張もあります。「関数やメソッドを十分小さい単位に分離し、適切に名前をつければ、その関数やメソッドが果たす役割は名前によって十分表現できる。構造化を適切に行えば、コメントを書く必要はない。コメントは最後の手段だ」という考え方ですね。

しかし、それでもコメントを書かない理由にはならないと思います。構造化と命名の工夫によってプログラムが理解しやすくなるのは確かです。しかし、それはプログラムの処理自体が分かりやすくなるだけであって、その処理の目的や背景、その処理を行う理由といった"プログラムの文脈"に関する情報が含まれないことには変わりありません。

つまり、ソースコードをコメントに書いておかなければ、プログラムを理解するのに極めて困難を要する場合が多々あるのだから、ソースコードには適切にコメントを書くべきであって、コメントを極力少なくする方針には賛同できない、ということです。

そして、どこにどのようなコメントを入れるか、というところに、ソフトウェアエンジニアとしてのセンスが現れると思っています。

実際、絶妙な場所に適切なコメントが入っているソースコードは、プログラムの解読が大変行いやすく、メンテナンスも容易で、大変ありがたいプログラムです。多少プログラム自体が上手く書けていなくても、そのソースコードをもとに作業する人間としてはコメントが適切に入っている方が速く理解できたりするのです。

エンジニアの美学としては、コメントが無くて、プログラムのみのソースコードを扱うほうがカッコいいのかもしれませんが。そこは格好よりも実利を尊重すべきだと思うんですよね。

というわけで、ソースコードに適切なコメントを書くことを決して軽視してはいけないし、コメントは最後の手段なんかではない、と言いたいのです。

「なるほど」と思ったら
↓このリンクをクリックを。



※この記事について指摘・意見・提案・感想などありましたら下のコメント欄にどうぞ。

2014年8月7日木曜日

リファクタリングは早めに行うべし

前回「既存のコードはなるべくいじらない」と書いてますが、それは他人が書いたコードとか、すでにテストを通過したコード、公開されて十分に使われているコードなどについてのことです。

自分で書いたコードで、リリース用のテストが始まる前の段階のものについては積極的に修正を行っていくべきでしょう。もしタイミングを逃してそのままリリースされてしまうと、今度は下手にいじれなくなってしまいますからね。

特にリファクタリングでコードの質を向上させておくことは後々のためになります。とはいえなかなか時間をとれないとは思いますが、例えば変数・関数・メソッドの名前の付け方だけでも見なおしておくことは役立ちます。

※この記事について指摘・意見・提案・感想などありましたら下のコメント欄にどうぞ。

2014年8月6日水曜日

既存の他人のコードは書き直したくても我慢する

以前から続いているプロジェクトに自分が新しく入った時とか、オープンソースで公開されているソースコードに追加・修正を加える時か、他人の書いた既存のコードを見ていると、ついつい全て書き直したい衝動に駆られたりします。

しかし、既存のコードを書き直すのは得策ではないです。以前そのコードは製品リリースの段階でテストされており、機能が正常に動作することは確認済みだったりするからです。下手にいじることはむしろ余計なバグを産むことになりかねません。

だから可能な限りもとのコードを尊重するのです。いじらなくてすむ部分はいじらない。シンプルです。

※この記事について指摘・意見・提案・感想などありましたら下のコメント欄にどうぞ。

2014年8月5日火曜日

既存のプログラムの修正時には「郷に従え」

他人が作ったプログラムに手を加える時とか、オープンソースで公開されているプログラムを利用する際に一部改変する時とか、既存のプログラムを修正する機会はIT系エンジニアには日常的な仕事の一部であると思います。

新規でソースコードをイチから書いていける場合と違い、既存のソースコードに追加・修正を加える際に意識すべきことは、「郷に入っては郷に従え」ということです。

同じ動作をするプログラムの書き方は無数にあります。単に望み通りの動作をさせたいだけだったら、既存のソースコードをほとんど無視して書くことも出来てしまいます。

でも、それをやってはいけません。既に書かれたコードにおいては、プログラム全体への影響が考慮されているものがほとんどであり、他の部分との整合性がとれています。だから、何かの機能を追加したり修正する場合には、既存のコードを出来る限り利用すべきです。これは無駄なバグの発生を防ぐ事にもなります。

他にも、変数の命名規則やインデントの体裁なども含めて、既存のコードに沿って追加や修正を行うべきです。そうすることでコードが読みやすくなり、バグも発見しやすくなります。

※この記事について指摘・意見・提案・感想などありましたら下のコメント欄にどうぞ。

2014年8月2日土曜日

ソースコードのコメントは「省力化」のために入れる

プログラミングにおけるソースコードに書くコメントについて、他のエンジニアと話す機会が最近あって、その方は「コメントは最後の手段」と言っていました。

要するにその方によれば、例えば関数やメソッドの名前・引数の名前などでコード自体が機能を説明するようにすべきであり、コメントに説明を書くのは最後の手段であると。

確かに、コード自体が機能を説明していることは重要です。関数やメソッドの名前・引数の名前は読めば何を意図しているのか分かるようにすべきであり、そのためなら多少名前が長くなっても構わないと思います。一つの関数やメソッドが長くなり過ぎたり条件分岐や繰り返しといった制御構造のネストが深くなり過ぎないように、適切に分割していくべきです。

それは確かなのです。しかし、どうしても「ソースコード自体が機能を説明する」ことには限度があります。その目的や意図や、動作の詳細を説明しきれない場合は結構多いのです。

もう1つ、ソースコード自体を細かい関数やメソッドに分割した場合、もし意図がわからなければ、結局次々と呼び出し元の関数やメソッドを追っていかなければいけません。これも実際に結構な労力です。

本当に何をしているか理解するには、やはり最後はソースコードを追っかけるしか無くて、関数やメソッドの名前・引数の名前だけで何をしているか説明できるというのは無理があると思っています。それは自分自身が書いたソースコードならばともかく、他人の書いたソースコードになれば、もはや不可能です。

ソースコードを追っかける際に一番難しいのは、やはりどういう意図と目的を持って書かれているかということで、そこはコメントに書いてあるのとないのとでは理解のスピードに雲泥の差が生じます。

Web上にあるプログラミング言語のリファレンスマニュアルを思い出してみると、関数やメソッドの引数の想定する型や説明、及び返り値のとりうる型や説明、そして関数が行う処理の説明が意図と目的が分かるように書いてあります。だから、例えばRubyやPHPの関数やメソッドを、その元となるC言語のソースコードを全く知らなくても使えます。ちょっと強引な例ですが、十分に詳細な説明があれば、その先のソースコードは追っかけなくてもよくすることができる、ということです。

もちろん、プログラミング言語のリファレンスマニュアル並みの詳細度を全てのプログラミングのソースコードのコメントに求めていたら、ソースコードを書く側が余りにも大変になってしまいますが、コメントがきちんと書いてあることによって、ソースコードの理解は格段に速く楽になることは間違いありません。結局ソースコードを追っかけることになったにしても理解度とスピードが全然違うでしょう。

書いたら捨てる使い捨てのコードならばともかく、後々のメンテナンスを自分や他人が行うことになるコードなのであれば、コメントを上手く入れることが非常に重要であり、特にライブラリ的に多数の箇所から参照される関数やメソッドの先頭には、引数の想定する型や説明、及び返り値のとりうる型や説明、そして処理の意図と目的が分かるようにコメント入れるべきである、というのが僕の意見です。それは後々の「省力化」になるのです。

※この記事について指摘・意見・提案・感想などありましたら下のコメント欄にどうぞ。

2014年8月1日金曜日

プログラミングにも「作曲」と「編曲」がある

プログラミングというのは、最初にロジックを考える部分と、実際のコードにしてからより良く動作するように改善を加えるリファクタリングの部分があります。これはいわば、音楽でいうところの「作曲」と「編曲」みたいなもんじゃないかと思います。

音楽が編曲によって化けることがあるように、プログラミングもロジックがイマイチでも、よくリファクタリングされ磨き上げたコードはバグもなく十分良い動作をしたりします。

音楽の場合は作曲者と編曲者が別々であることはよくありますが、プログラミングの場合はロジックを考える人とリファクタリングを行う人が分かれておらず、ほとんどの場合で同一人物が行います。なので、うまく頭を切り替えて、両方を意識しながら作業することが大切です。

ロジックを最初に思いついた方法で実装しただけで終わりにしまう人が多いですが、そこからのアレンジも大切なんですよね。

※この記事について指摘・意見・提案・感想などありましたら下のコメント欄にどうぞ。

2014年7月31日木曜日

動的型付けを「複数の型を持てる」と考える

PHPやRubyなど、動的型付けをもつ言語を僕も普段から使っています。ただ、動的型付けに対しても、僕は明確に変数の型を意識します。

そもそも、動的型付けに対して、「型を意識しなくてよくなる」と考えるのは間違っていると思っています。そうではなく、「一つの変数が複数の型を持てる」と考えるべきかと。

例えばPHPだと、ある関数の返り値は場合によって整数かもしれないし文字列かもしれません。失敗時にはfalseだったりします。その関数の返り値を変数に代入すると、この変数は整数かもしれないし文字列かもしれないし真偽値であるかもしれません。しかしこの特徴によって、ソースコード記述の柔軟性を上げることが出来るのですね。

ただ、やはり変数を取り扱う上で、変数の型を意識しないと思わぬバグを産んだりします。だから、「型を意識しなくてよくなる」のではなく、「一つの変数が複数の型を持てる」と考えるべきなのです。

※この記事について指摘・意見・提案・感想などありましたら下のコメント欄にどうぞ。

2014年7月30日水曜日

開発における "あと一歩" の追求

例えば、UIの配置やプログラミングのパターンを、あと1つだけ多く試してみるとか。手間としては、それほど多くなるわけではないでしょうが、これをやるかやらないかの違いは大きいと思います。

時間との兼ね合いもありますけれども、特にソフトウェアにおいてはちょっとした違いが積み重って全体の印象を決めています。むしろ地味な違いほど効たりします。

だから、ソフトウェア開発において、"あと一歩" の追求は時間に切羽詰まっていない限りは重視したいと思うのです。

※この記事について指摘・意見・提案・感想などありましたら下のコメント欄にどうぞ。

2014年7月29日火曜日

UI設計では素朴な感覚を大切にする

ソフトウェア開発におけるUI設計は、経験や理論も影響してくるものではありますが、それより大切だと思っていることは「素朴な感覚」です。

まっさらな気持ちで、初めてそのソフトウェアを触った人のような気持ちになって操作し、何を感じるか。そこで「使いやすい」と感じられるか。何か足りないと思うことはあるか。多すぎると思うことはあるか。変えたほうが良いと思うことがあるか。などなど・・・。そこでかすかに感じるわずかな違和感に気づくことが何よりも重要です。

確かにプログラミングには経験や理論もファクターとして大いに絡んできます。しかし、そのプログラミングを通して作り上げ、最終的にユーザとの接点になるUIにおいては、何も知らない人間の感覚になる必要があります。

こういった感覚の切り替えもソフトウェア開発の面白いところですね。

※この記事について指摘・意見・提案・感想などありましたら下のコメント欄にどうぞ。

2014年7月25日金曜日

git diffって多用するよね

git diffは非常によく使うコマンドの1つで、僕の仕事のクオリティを支えてくれているツールでもあります。また、difftoolにvimdiffを用いたgit difftoolも同じくらいよく使います。

僕はかなりこまめにgit diffを使います。プログラミングをしていると、ちょっと書いたらgit diffで差分を見て、動作確認し、またちょっと書く、みたいな感じです。差分を確認せずに一気に書くことはほとんどないです。

あとコミット前にはインデックスとHEADの差分をgit diffとgit difftoolの両方で確認します。ここで原則として差分については全て余すところなく確認します。

あと、ローカルブランチのコミットをgit merge --squashでまとめて提出用ブランチにした際も、提出用ブランチの直前との差分を確認しますが、この際はざっと目を通す感じですね。

こんな感じです。実に利用シーンは多いです。ちなみに差分アルゴリズムはhistogramがおすすめです。difftoolにvimdiffを用いる場合に、差分作成アルゴリズムを変更する方法については過去の記事を参照。

※この記事について指摘・意見・提案・感想などありましたら下のコメント欄にどうぞ。

2014年7月24日木曜日

言われたとおりにやるエンジニアは二流

依頼者から言われた通りのものを作る。と言えば一見問題ないように感じますが、ただ言われたとおりにやるだけでは、それはソフトウェア開発エンジニアとして二流だと思ってます。

仕事の依頼というものは、それ自体が依頼者の本当に欲しい物を示しているのではありません。依頼者が、欲しい物を伝えようとして表現した結果が仕事の依頼なのです。そこには依頼者が表現する際にどうしてもズレや抜け漏れが生じていると考えなければいけません。

だから、依頼を受けたエンジニアとしては、依頼通りのものを作る事を目指すのではなく、依頼を通じて依頼者が本当に欲しがっているものを推理し、依頼をチューンナップしてあげる必要があります。

上記の話は、ソフトウェア開発においてウォーターフォール型開発だと要件定義の段階で実際によく言われる話です。しかし、ウォーターフォール型開発のように、ステップが明確に分かれていない開発が多くなっています。アジャイルや、それに類似した開発手法では、要件定義・設計・実装は明確に分かれておらず、担当者も同じだったりします。僕が関わっているプロジェクトもそうですね。

そうなると、より担当者の判断が求められるようになってきます。ウォーターフォール型開発だったら、要件定義の段階で全ての仕様について依頼者の同意を得てから次のステップへ進むという方法でしょうが、アジャイルや類似した開発手法の場合そうは行きません。そもそも仕様はどんどん変更されるのが前提ですから、担当者自身が判断して実装して実際に動く状態まで作って依頼者に見せてしまえばいいし、それしかないのです。

今後ますます、言われたとおりにやるエンジニアよりも、言われたことを上手に解釈して意図を汲み取り、実装まで行って動く形にして、依頼者を満足させられるエンジニアが評価されていくでしょう。

※この記事について指摘・意見・提案・感想などありましたら下のコメント欄にどうぞ。

2014年7月23日水曜日

プログラミングは "新規" と "追加・修正" で全く異なる

最近思うんですが、プログラミングっていうのは、それが「新規」つまり「そのプロジェクトに関しての過去のコードが全く存在しない状態からコーディングする」のと、「追加・修正」つまり「そのプロジェクトに関して既にコードが存在し、それに対して追加あるいは修正を加える」のとでは、全く異なったものになりますね。もう少し詳細に言うならば、「追加・修正」の中でも、たとえプロジェクトに関しての過去のコードがあったとしても、実装しようとしている機能が他の機能から比較的独立しており、かつ、そこに関する部分のコードがまだ存在しない場合、「新規」に近いとみなすことができます。

さて、「新規」の場合、ソースコードの配置(どのファイルにどういった内容をコーディングするのか)、論理構成(どんなクラス・メソッドを作成してどのような役割を分担させるか、あるいはクラス・メソッドが既に用意されているフレームワークの選定)など、自分で骨組みを考えていきます。また、細かい話で言えば、クラス・メソッド・変数などの命名規則、空白や括弧のコーディングスタイルなども自分で決めていくわけです。

一方、「追加・修正」の場合は、上記で書いたようなことは(中途半端な状態で引き継いだのでない限り)元から全て存在しています。ですから、ソースコードの配置を勝手にできません。例えば画面描画のためのソースコードを集めて置いてあるフォルダに、いきなりDB接続用のソースコードを置くなんて暴挙は言語道断です。あるいは、すでにあるクラスと同じ役割のクラスを勝手に作ったら自分でさえ混乱しかねません。変数の命名規則を無視すると他のコードとの連携でミスを誘発し、バグの温床になります。要するに、既に存在するコードの規則に従うことが原則です。

従って、同じプログラミングとはいえ、「新規」と「追加・修正」では頭を切り替えなければいけません。

※この記事について指摘・意見・提案・感想などありましたら下のコメント欄にどうぞ。

2014年7月18日金曜日

SQLを久々に直接書いてWeb開発者として思ったこと

久々にSQLを直接書きました。とうのは、最近はORマッパーを使うことが多くて、直接SQLを書くことがめっきりなくなっていたからです。しかし今回は既存のコードに手を加える作業をするという状況で、既存のコードがORマッパーなど使用していないコードだったものですから、SQLを直接書くことになりました。

別にDBの専門家ではないので、パフォーマンスのチューニング方法などはあまり詳しくありません。もちろん速度は考慮して書きますが、それは基本的な部分であって、高度なチューニング(例えばDBMSの種類ごとの最適化やストレージエンジンごとの違いの考慮など)はできません。

とは言うものの、そこまで高度なチューニングが求められる場面は、Webアプリケーションにおいて少ないですし、今後も少なくなっていくように思います。基本的な原則(例えば、不要なレコードは取得しない=WHERE句でなるべく絞り込む、など)に則っていればよいと思います。以前はSQLの方で最適化しなければならなかったようなパターンも、DBMS自身の進化によって高速化している例もありますし。

Web開発者としては、そもそもSQLをチューニングしなければならないようなDB構成を避けるという方向性の方がよいような気もします(既存のシステムだとそうも行きませんが、そこはDBの専門家の出番でしょう)。

ということで、Web開発者の自分としては、SQLについては今後も基本的な原則は学んでいこうと思いますが、DBMSの種類ごとの最適化やストレージエンジンごとの違いの考慮といった事項は、DBの専門家にまかせておこうと思っています。

※この記事について指摘・意見・提案・感想などありましたら下のコメント欄にどうぞ。

2014年7月17日木曜日

システム構築に必要な「統一性のセンス」

エンジニアとしてITシステムの構築を生業とするにあたっては様々な能力を必要とされますが、中でも重要な能力だと思っているのが「統一性のセンス」ですね。

これは、直接ユーザの目に触れるユーザインターフェース(UI)についても言えることですし、直接ユーザの目に触れないプログラミングやデータベース構造といったものについても当てはまることです。

例えばUIについては、ボタンの配置の方向や順番や色、アイコンの形、語彙表現など様々な要素について統一性を持たせることが、使いやすさに大きく影響します。

プログラミングについても、変数名・クラス名・メソッド名などの命名規則、論理的構造のパターンなどに統一性を持たせることで、バグの低減やメンテナンス性の向上を図ることができます。

システム構築には美的センスが求められる、と言う場合、その多くは「統一性のセンス」を意味しているのです。なぜなら、統一性のあるUIやソースコードは美しいものだからです。芸術作品では「混沌のセンス」も美的センスとしてアリなのでしょうが、システム構築にはありえないですからね。

※この記事について指摘・意見・提案・感想などありましたら下のコメント欄にどうぞ。

2014年7月16日水曜日

他人のソースコードを読む際には推理能力も要る

昨日、プログラミングの際には考え方と目的も記録を残せと書いたんですが、自分はそうするよう気をつけていても、実際に仕事で扱う既存のソースコードにおいて、考え方と目的をコメントや公開サイトや付属ドキュメント等に書いていてくれているのかというと、まあ残念ながら書いてくれていない場合も多いわけですよ。

そういう時は仕方ありませんから、まるで推理小説の名探偵よろしく推理するしかありません。例えば変数やメソッドの名前も人によって微妙に用法が異なったりするので、ソースコード全体の傾向から、その名前が意味する所を推し量ったりとか。静的にソースコードを解析するだけでは分からない時は、デバッグツールを使って実際の動きを見ながら、コードの意味を分析したり、わざとエラーを起こさせてみたり。Javascirptの時なんかはよくやる手段です。

その意味では推理能力も必要ですね。つくづくプログラミングってのは思考を駆使すると思うんですよ。だから楽しいんですけどね。

※この記事について指摘・意見・提案・感想などありましたら下のコメント欄にどうぞ。

2014年7月15日火曜日

プログラムを書いたら考え方と目的も記録を残すこと

プログラミングをする過程で、他人の書いたソースコードを読んでいて本当に強く思うんですけど、その実装方法に至る経緯や考え方や目的が分からないと非常に解読に苦労します。

単なる処理の動きだけならソースコードを読めば分かります。でも、例えばどういう時に使うクラスやメソッドなのかとか、以前別の方法で実装したけれど何らかのトラブルがあって直したとか、そういう情報がないときちんと理解出来ないんですよね。

だからソースコードに考え方と目的を、コメントとして残しておくか、あるいはRedmineなどのタスク管理システムを使っているならチケットに書いておくとか、何らかの方法で記録しておくべきだと思います。場合により使い分けるといいと思いますね。

これは将来そのソースコードを読む他人のためでもあり、そして後から修正をすることになった時の自分のためでもあります。忘れるものですからね。

※この記事について指摘・意見・提案・感想などありましたら下のコメント欄にどうぞ。

2014年7月13日日曜日

gitのpush前にmerge --squashとpullとrebaseを

gitでどうブランチを切ってコミット・プッシュするかの運用方法については様々な意見というか流派(?)があるように思います。僕自身も複数人数のチームで開発を実際に行う中で、こうしたらいいんじゃないかって思っている方法を書いてみようと思います。

まず開発のタスク管理にはredmineを使っている、という背景があります。gitの共有リポジトリはredmineと連携させていて、共有リポジトリにプッシュしたコミットのメッセージにチケット番号を記載しておくと、自動的にredmineのチケットからリポジトリビューアにリンクされるようになっています。そのような背景から、チケットごとにコミットを1つにまとめています。

さらに、共有リポジトリへプッシュする際は、自分の名前が付けられたブランチにプッシュすることにしています。(masterへのマージはmasterブランチ管理者以外は行わない。)例えば僕はkasaiという名前のブランチを作成して、そこへ自分が担当するチケットを解決するコミットを行い、それを共有リポジトリへプッシュします。

masterブランチ管理者は、共有リポジトリへプッシュされた他の担当者のブランチをローカルリポジトリへプルしてmasterへのマージを行い、改めて共有リポジトリへプッシュします。(つまり、共有リポジトリのmasterへのプッシュを行えるのはmasterブランチ管理者だけです。)

この辺までは結構よくある運用方法でしょうね。ここまで全体的な流れの話を書きましたが、次に、各担当者が個人的に行う運用方法についてです。

僕の場合、ローカルリポジトリにはローカル用ブランチを作って作業しています。ローカル用ブランチは自分のためだけのブランチで、一度行った変更を後のコミットで元に戻したり、試行錯誤の汚い履歴が混在していて、そのまま共有リポジトリにプッシュするなんて考えられない代物です。ちなみに僕はローカル用ブランチには local/yy.mm.dd という名前を付けています(yy.mm.ddは作成時の日付、1日に複数作成した場合はyy.mm.dd-2などとする)。

とういことで、ローカル用ブランチで試行錯誤して、完成したら提出用ブランチ(前述した例ではkasai)にまとめて取り込むという方法を採っています。その際にはmerge --squashを使います。

なお、提出用ブランチにmerge --squashされた後のローカル用ブランチは消してもいいのですが、バックアップの意味もあるし、コードが動かなくなった際に履歴が残っていると原因究明にも役立ったり、元に戻したりできるので残しておくことにしています。

では、提出用ブランチをこのままpushすればいいかというと、ちょっと考えるべき問題があります。pushする前に、共有リポジトリのmasterに、自分が元にした時点から変更がいくつも加わっている場合、コミット内容がmasterと競合しないにもかかわらず、仕様変更によりコードが動かなくなってしまう可能性があります。例えば、他人の担当範囲で定義されていた関数やメソッドを呼び出してコードを書いたが、自分がローカルで作業している間に、その関数やメソッドの挙動を変えるコミットがmasterに既にマージされていた、といった場合です。(この問題に関してはGitユーザマニュアルの「マージコミットの分割が1本線の履歴の分割よりも困難となる理由」の解説が分かりやすいです。)

だから、push直前に、最新のmasterを改めてpullで取得し、その最新のmasterにこれからpushしようとする変更を統合した状態で動作することを確認しておきたいんですね。そのためにrebaseを行ます。つまりpush直前に、自分のブランチをpullで取得した最新のmaster上にrebaseするのです。

こうすることで、上記のようにmaster側に知らないうちに仕様変更が加わっていて、競合が発生しないにもかかわらずコードが動かなくなる、という事態に陥る危険性を(ゼロではないにしても)かなり減らすことができます。また、もしそのような事態になったとしても、rebaseしておくことで原因の究明はぐっとやりやすくなります(当然ながら、これはpush前のコミットだからrebaseしてもいいのであって、たとえ提出用ブランチでも、一旦pushした後のコミットは決してrebaseしてはいけません)。

まとめると、こういう流れになります。
  1. ローカル用ブランチを作成し開発を行う。コミットは適宜好きなように行う。
  2. 提出用ブランチにてmerge --squash でローカル用ブランチの変更をまとめて取り込む。まとめる単位はredmineのチケット単位とする。
  3. masterブランチにてpullで共有リポジトリの最新の状態を取り込む。
  4. 提出用ブランチにてrebaseで変更を最新のmaster上に移し替える。
  5. rebaseされた提出用ブランチにて共有リポジトリへpushする。
  6. (masterブランチ管理者のみ) 各担当者の提出用ブランチブランチをpullし、ローカルでmasterへのマージを行い、共有リポジトリへpushする。
これが今のところいいんじゃないかと思っている方法です。

※この記事について指摘・意見・提案・感想などありましたら下のコメント欄にどうぞ。

2014年7月11日金曜日

オープンソース時代こそ「コメント力」を

オープンソースとしてソースコードが公開されているソフトウェアを仕事で使ってたりするんですが、その際にソースコードを読み込んで目的に合わせてコードを追加したり改造したりするんですよね。で、何が一番大変かって言うと、そのソースコードを書いた作者の"意図を読み取ること"です。

プログラムの動作自体はソースコードそのものを読めば分かります。ただ、この変数をここで加算して、この関数に引数として渡して・・・といったプログラミング言語の処理自体は分かっても、そのソースコードが"何を目的に書かれているのか"が分からなければ意味がありません。

結局、ある一部分の動作がどういう意味を持つのかを知るために、関連するソースコードがを読み漁り、相当広い範囲を調べてようやく分かったりします。ただ、そこまで時間がかかるのには理由がありまして、ソースコードに"コードの目的・意図を記述した"コメントがほとんど無い場合にそうなるのです。

前にも書きましたが、ソースコードを読めば分かるってのは嘘ですからね。プログラムの機械的動作は確かに分かりますが、コードの目的や意図まで読み取るのは簡単ではありません。もちろんソースコードの関連する部分を含め広い範囲を読めば見えてくるのですが、しかしそれもどうなんでしょうか。

やはり、オープンソース時代であるからこそ、ソースコードを読む人に対する配慮は大切だと思うし、だからこそ、コードの目的や意図を分かりやすく記述できる「コメント力」が大切だと思うんですよね。

※この記事について指摘・意見・提案・感想などありましたら下のコメント欄にどうぞ。

2014年7月10日木曜日

プログラミング言語のバイリンガル以上を

現在僕が関わっているプロジェクトは1つはRuby、もう1つがPHPをメインの言語として採用しています。自分自身の経験としても、PHPとRubyは得意とする言語なので両方とも言語を使うこと自体に苦労はありません。その他にもJavascriptは両方のプロジェクトで多用していますし、補助的にPythonも少しだけ使っています。あとは汎用言語ではありませんがシェルスクリプトも駆使します。HTML・CSSの知識は言うまでもありません。

実際プロジェクトの開発を進めてて思うんですが、2つ以上の得意な汎用言語を持っておくと色々メリットが有るんですよね。別にRubyとPHPじゃなくてPythonでもC#でもJavaでもPerlでも何でもいいんですけどね。とにかく2つあれば、色々比較ができるわけで、両方の言語を実際に使って開発した体験・経験を比べることによって言語の特徴が体感覚として分かるわけですよ。

例えば片方の言語で慣れたやり方を、もう一方の言語で実装しようとした時にすんなり行かないことがあったら、そこで言語の強みと弱みが分かります。また、そこでもう一方の言語で実装するときの最適解を考えますから、これも力になります。

それに、複数の言語での実装を知っていると、より汎用的なロジックを考えられるようになります。特定の言語に依存したロジックではく、別の言語でも問題なく実装できるようなロジックを考える傾向がつきます。その方がバグも出にくく、品質の工場にも寄与すると考えられますね。

ともあれ、プログラミング言語はバイリンガルになっておくと色々得をします。もちろん2つに留まらず、3つ4つと大いに越したことはありませんが、まずは2つを目指すとよいでしょうね。

※この記事について指摘・意見・提案・感想などありましたら下のコメント欄にどうぞ。

2014年7月5日土曜日

ググっても解決しない問題にこそ力を注ぐ

今のソフトウェア開発ってフリーソフトとかオープンソースとか皆が共通に利用できる資源が整ってまして、仕事で使うソフトウェアも手に入ります。その結果優れたソフトウェアは皆が同じものを使うようになります。得られたノウハウもウェブページやブログや各種SNSで公開していくために、困ったことがあればググればほとんど解決できるんですよね。その意味でネットが無ければ仕事になりません。

だから知識は重要だし、他人が既に見つけた問題の解決策を素早く見つけることも必要ではあることは確かです。僕も散々そう言ってますし。でも、そこには当然ながら限界がありまして、仕事をしていれば必ず、そう"必ず"いくらググっても解決策を見つけられない問題にぶちあたるものなのですね。

その時こそが本当に力を注ぐべき時です。ググって解決できるものをサッサと片付けるのは、この"いくらググっても解決策を見つけられない問題"に時間を掛けるためだと言っても過言ではありません。

ちなみに僕は"いくらググっても解決策を見つけられない問題"にぶちあたるのを、いつも楽しみにしてます。まあ、ググってサクサク問題を片付けるのもシューティングゲームみたいで楽しくはありますが、やはり本気で頭を使う時が一番楽しかったりするので。

※この記事について指摘・意見・提案・感想などありましたら下のコメント欄にどうぞ。