Mercurial入門!

この記事は「Mercurial Advent Calendar 2011」の一環として書いています。前日の16日目は、@troterさんの「mercurial-backlog拡張を作った中で知ったこと」でした。17日目は私、@worarsが担当させて頂きます。

さて、何を隠そうAdvent Calenderなるイベントは初めて参加する訳で、さらに言えばMercurialを触り始めてまだ数週間。お誘いを受けたので参加してみたものの何を書いて良いやら・・・。色々とツッコミどころが出てくるとは思いますが、どうかお手柔らかに。

何はともあれインストール

今使っているPCはWindows(Vista)なので、「TortoiseHg」というGUI付きのMercurialをインストールします。まずは、ココのサイトから日本語版がダウンロード出来るのでダウンロードします。現時点でのバージョンは、TortoiseHg 2.2.1 (with Mercurial 2.0.1)です。あとはインストーラでインストールするだけです。ここで注意しないといけないのは、リポジトリ内に日本語を含むファイルを含める場合、そのまま「hg add 日本語のファイル.xls」などとすると失敗してしまう事です。これを回避するには、TortoiseHgのメニューから「ユーザ設定」を選び「エクステンション」の中から「win32mbcs」にチェックを入れます。これで日本語のファイルも問題なく扱えるようになります。複数OS間で連携する場合は、もう少し考慮しないといけない点があると思いますが、その辺りは15日目の「Mercurial の文字コード設定」がとても参考になると思います。

さて、これで実行環境が整いました。ヤッター、これで明日からMercurialが使えるぞ!・・・と言いたい所ですが、そういう訳にも行きません。そもそも何でMercurialを使うのでしょうか?ここまで書いておいて今更ですが。

Subversionと比較してみる

現在の開発現場では、cvs,vss,Subversionなどの中央集権型のバージョン管理ソフトが多く導入されています。この状況下でMercurial等の分散型バージョン管理ソフトをより普及させる為には、それなりの動機づけが必要かと思います。ですので、まずはSubversionと比較してそのメリット、デメリットを見てみたいと思います。

メリット
  • ローカルにリポジトリを持つのでオンラインでなくてもいつでもコミット出来る
  • より細かい単位でコミット出来る*1
  • スケールアウトが簡単

などといった所でしょうか。もちろん便利なコマンドが増えている等の細かいメリットも沢山あります。*2

デメリット
  • 仕組みがちょっと複雑=覚えるコマンドが多い
  • 分散型なので一元管理されているか不安になる*3

簡単に思いつく範囲ですが、上記の様なメリット、デメリットがあります。現在、Subversion等で運用している企業がMercurial等の分散型バージョン管理ソフトへ移行する為には、上記のメリットがデメリット+移行の手間を上回る必要があります。この為、今の私の環境では、残念ながら導入するのは難しそうです。もしチャンスがあるとすればレスポンスが悪化して環境を強化せざるを得ない時でしょうか。この時は、スケールアウトが簡単に出来る分散型のバージョン管理ソフトが俄然有利になりますね^^*4
なので、私の場合は、まだまだSubversionを使う日々が続きそうです。もちろんプライベートはMercurialに切り替えるつもりですが。現場で使えてる方々が羨ましい。

という事で今日はこの辺りで。次回、18日目の@tksnさんの「低コストで少人数プロジェクトに最適なバージョン管理システムを探そう!」に期待を寄せつつ眠りに就きましょう。おやすみなさい。

参考にしたサイト

最後にMercurialを始めるに当たって参考にさせて頂いたサイトを紹介致します。

入門Mercurial Linux/Windows対応

入門Mercurial Linux/Windows対応

*1:Subversion等では、気持ちの問題ですが、コミット=皆と共有なので、ある程度まとまってからきれいな状態のソースコードしかコミットしたくなくなる。一方、分散型の場合は、あくまでローカルでのコミットなので今日はもう疲れたから帰る等といったタイミングでもコミット出来る・・・気がする。

*2:rebaseとか超便利そう。ブランチが切りやすいのも良いですね

*3:中央リポジトリを作れば、ほぼ解決しますが

*4:負荷分散については、「入門Mercurial」の書籍でもコラムの中で触れられていました。

DBFluteのreplace-schema

久しぶりにDBFluteを使ってみたら、replace-schemaを使う時にisDropGenerateTableOnlyがなくなっている事に気がついた。やっぱりあるならあったで便利なオプションなので、復活しないかなと思う今日この頃です。

理由としては、以下の様な事が挙げられます。あくまで自分の所の環境だけですが・・・。

複数のアプリがスキーマを共有している場合

ホントはダメだと思うのですが、今の環境だと結構ある。*1こういった場合、同じスキーマ内にアプリA用のテーブルとアプリB用のテーブルが出来てしまうので、replace-schemaをアプリAでやる場合は、dropされるテーブルをアプリAのテーブルだけに留めたい。現状だとスキーマ内の全てのテーブルがdropされてしまう気がする。*2

アプリに直接関係ないビューを作る事がある

例えばカッコ悪いやり方かもしれないが、「create view テスト系 as select * from dual」*3見たいなビューをテスト系と本番系に作っていてこうしておくと、どんな環境から接続した場合も「select * from tab」とかやると自分が今どこに繋いでいるかハッキリするので指差し呼称とセットで実施していたりする。このビューの場合はDDLで作る時に本番環境なのか、テスト環境なのかの判定が出来ないと作れない。まぁ、本番環境は一度リリースしたらほぼreplace-schemaをやる事はないので、常にテスト系に合わせて作っておけば良い気はする。

見たいな感じでisDropGenerateTableOnlyがあったらなーと思いました。作成するときは自作のDDLを使うので、削除するときも自作のDDLで出来れば良いかも^^;

余談ですが、DBFluteのContainerTestCase良いですね。injectがめっちゃ便利。PlainTestCaseを見ると現在時刻の取得とか色々便利なメソッドも詰まっているので便利そう。後は、Actionのテストの時にバリデーションをJUnit上から実行出来ればかなり良い感じの開発環境が出来そうだ。id:newtaさんの方法などを参考にして作ってみようと思ってます。基底クラスに持たせずにユーティリティー見たいな感じでやりたいな。

*1:特に見える化とかがちょっと貸して的なノリで乗っかってくる時がある。迷惑な話だけど・・・

*2:特定のテーブルだけ無効化出来れば解決!

*3:oracle

麻雀って何ぞ!?

面白そうな記事を見つけたのでPythonの勉強がてらやってみた。

あなたのスキルで飯は食えるか? 史上最大のコーディングスキル判定
http://www.itmedia.co.jp/enterprise/articles/1004/03/news002.html

制限時間3時間とあるが何とか2時間半くらいで出来た。Pythonの構文とかググったりしたので習熟した言語でやれば2時間くらいか。Pythonの勉強なので、出来るだけPythonの機能(set)とかを使ってみました。でも出力フォーマットとか整えていなかったり、明らかにリファクタリングできる所があったりするけど・・・。なんていうか飽きたんだよ(-_-)許して下さい。

以下ソースコード(手抜き)です。

result_list = []

def get_shuntsu(x, tehai):
    if x in tehai and x + 1 in tehai and x + 2 in tehai :
        work_tehai = list(tehai)
        work_tehai.remove(x)
        work_tehai.remove(x + 1)
        work_tehai.remove(x + 2)
        return [x, x + 1, x + 2], list(work_tehai)
    else :
        return [], list(tehai)

def get_kotsu(x, tehai):
    if tehai.count(x) >= 3 :
        work_tehai = list(tehai)
        [work_tehai.remove(y) for y in (x, x, x)]
        return [x, x, x], list(work_tehai)
    else :
        return [], list(tehai)

def make_mentsu(tehai, fixed_tehai):
    for x in tehai :
        mentsu, amari = get_shuntsu(x, tehai)
        if mentsu :
            if len(amari) == 1 :
                result_list.append(fixed_tehai + [mentsu, amari, (amari[0],)])
                return
            if len(amari) == 2 :
                if amari[1] - amari[0] == 0 :
                    result_list.append(fixed_tehai + [mentsu, amari, (fixed_tehai[0][0], amari[0])])
                elif amari[1] - amari[0] == 1 :
                    machi = []
                    if amari[0] > 1 :
                        machi.append(amari[0] - 1)
                    if amari[1] < 9 :
                        machi.append(amari[1] + 1)
                    result_list.append(fixed_tehai + [mentsu, amari, tuple(machi)])
                elif amari[1] - amari[0] == 2 :
                    result_list.append(fixed_tehai + [mentsu, amari, (amari[0] + 1,)])
                return
            
            make_mentsu(amari, fixed_tehai + [mentsu])
        
        mentsu, amari = get_kotsu(x, tehai)
        if mentsu :
            if len(amari) == 1 :
                result_list.append(fixed_tehai + [mentsu, amari, (amari[0],)])
                return
            if len(amari) == 2 :
                if amari[1] - amari[0] == 0 :
                    result_list.append(fixed_tehai + [mentsu, amari, (fixed_tehai[0][0], amari[0])])
                elif amari[1] - amari[0] == 1 :
                    machi = []
                    if amari[0] > 1 :
                        machi.append(amari[0] - 1)
                    if amari[1] < 9 :
                        machi.append(amari[1] + 1)
                    result_list.append(fixed_tehai + [mentsu, amari, tuple(machi)])
                elif amari[1] - amari[0] == 2 :
                    result_list.append(fixed_tehai + [mentsu, amari, (amari[0] + 1,)])
                return
            
            make_mentsu(amari, fixed_tehai + [mentsu])

if __name__ == "__main__" :
    tehai = [1, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9]
    tehai.sort()
    
    for x in tehai :
        if tehai.count(x) > 1 :
            work_tehai = list(tehai)
            [work_tehai.remove(y) for y in (x, x)]
            make_mentsu(work_tehai, [[x, x]])
        
        make_mentsu(tehai, [])
    
    [result.sort() for result in result_list]
    result_set = set([repr(result) for result in result_list])
    for result in result_set :
        print result

出力結果こんな感じ。マンズ(1-9)、ソーズ(101-109)、ピンズ(201-209)、字牌(適当にバラバラ)のようにデータを定義すればマンズ以外にも対応出来そう。

[[1, 1, 1], [2, 3], [4, 5, 6], [7, 8, 9], [9, 9], (1, 4)]
[[1, 1, 1], [2, 3, 4], [5, 6, 7], [8], [9, 9, 9], (8,)]
[[1, 1], [1, 2, 3], [4, 5], [6, 7, 8], [9, 9, 9], (3, 6)]
[[1, 1, 1], [2, 3, 4], [5, 6], [7, 8, 9], [9, 9], (4, 7)]
[[1, 1, 1], [2], [3, 4, 5], [6, 7, 8], [9, 9, 9], (2,)]
[[1, 1, 1], [2, 3, 4], [5, 6, 7], [8, 9], [9, 9], (7,)]
[[1, 1], [1, 2, 3], [4, 5, 6], [7, 8, 9], [9, 9], (9, 1)]
[[1, 1], [1, 2], [3, 4, 5], [6, 7, 8], [9, 9, 9], (3,)]
[[1, 1, 1], [2, 3, 4], [5], [6, 7, 8], [9, 9, 9], (5,)]
[[1, 1], [1, 2, 3], [4, 5, 6], [7, 8], [9, 9, 9], (6, 9)]
[[1, 1], [1, 2, 3], [4, 5, 6], [7, 8, 9], [9, 9], (1, 9)]

初めてのPythonを読んで

「初めてのPython」読み終わったー\(^o^)/

やっぱりオラエリーの本は、読み終えた時どっと疲れが出てくるな。でも充実感も出てくる。って事で感想をば。
まず、「初めてのPython」は入門書としてとても良い本でした。Pythonをやるなら読んでおいて損はない感じがしました。ただ、Python以外のプログラム言語を知っている方にとっては、少々くどい感じがするかも知れません。もちろんこれは、Pythonで初めてプログラムを触るという方向けの配慮がなされているからで、仕方がない事なのですが・・・。

でも本書の良い所は、見出しがとても分かりやすい事。見出しの内容とソースコードの部分さえ読めば、ある程度飛ばして読めるのでストレスもそんなに堪りません。しかもfor文の内部的な仕組みやリスト内包表記の速度面での優位性、演算子のオーバーライドの仕方、例外、コンテキストマネージャ等のPython特有の事について細かく書いてあるのでその辺りだけ飛ばさずに読めば、効率よく学習出来ます。例外の所等は普段Java屋の僕にはちょっと衝撃だった。基底クラスがなくても良いなんて!さすがスクリプト言語といった感じ。*1あとは、所々でC言語との比較が良く出てくるのでC言語が分かる人には更に読みやすさが上がるかも知れません。

全体の感想としては、入門書としては若干重いかもしれないといった所。他の入門書の方がたぶん読みやすいだろう。しっかり勉強したい人向けですね。他の入門書は読んだことがないので分かりませんが、サクっと読みたい場合は、そっちのが良いかもしれません。

でもやっぱPython良いですね。最近仕事で使う為のちょっとしたツールをPythonで書いてみた感想等も含めて自分の中でPythonの評価がかなり上がってきている。あくまで自分の中でだけど、PythonRuby,Perlの図式が出来つつある。この辺りは好みだろうなぁ。一つの事を実現するときに色々な方法があるのか、出来るだけ統一するのか。言語の設計思想の問題なので深いですよね。

さて、次はDjango辺りを勉強していこうかね。

初めてのPython 第3版

初めてのPython 第3版

Pythonスタートブック

Pythonスタートブック

10日でおぼえる Python 入門教室

10日でおぼえる Python 入門教室

リバースエンジニアリング ―Pythonによるバイナリ解析技法 (Art Of Reversing)

リバースエンジニアリング ―Pythonによるバイナリ解析技法 (Art Of Reversing)

*1:基底クラスはなくても例外として活性化させる事は出来るけどビルドインの例外クラスなどもあるので実際はそれを基底クラスにした方が良いとは思います。

Androidのデバッグで躓いたのでメモ

ようやく重い腰を上げアプリを作ろうとした所、いきなりデバッグで躓いたのでメモ。1年くらい前に少しいじった時は、すんなり出来た気がしたけど、今日は何故かうまく行かなかった。

必要な設定

AndroidManifest.xmlに以下の2つの設定が必要。
・ApplicationのDebuggableをtrueにする
・Permissionsにuses-permissionのSET_DEBUG_APPを追加

ごみ掃除

基本的には、上記2つの設定をすればブレークポイントを設定してのデバッグが出来るようになる。しかし、プロセス等が残る為、場合によって以下の2つの事をしないと「Waiting for Debugger」と表示される事がある。
eclipseの再起動
コマンドプロンプトから「adb kill-server」を実行。

自分の環境だととりあえず上記の事をやれば安定してデバッグ出来るようになった。でもちょっと手間が掛かり過ぎだよなー。もう少しスマートなやり方はないだろうか?

「アジャイルサムライ」を読んで

読書熱第2段という事で、「アジャイルサムライ」読みました。一言で所感を書くと「楽しくて読みやすい」といった感じでしょうか。

僕は学生時代に「初めてのアジャイル開発」等を読んでいたので目新しい事ばかりではなかったのですが、この本からはケント・ベック達がアジャイル宣言を行った時の熱狂が伝わってくるようでした。
この熱量こそが、アジャイルを行う上での一番重要な要素かもしれません。常に改善をしていこうという熱量です。

この本の中にこんな言葉がありました。「師を仰ぎ、師を追いかけ、師に歩調を合わせ、師の意図を汲み、そして自らが師になるのだ。」
美しい言葉です。そしてプログラマのコミュニティーはギルド文化だと感じさせられる言葉です。自分もこうありたい。

感情的な事ばかりを書いてしまいましたが、この本の中にはアジャイルな開発を行う為の実践的なプラクティスやツールがいくつも紹介されています。
そういった意味でもアジャイル開発に興味がある方にとっては、一読の価値がある書籍だと思います。僕はもうあと何回かは読み直すことになりそうな予感w

この読書熱を継続させる為に、書籍の中で紹介されていた実践アジャイルテストをアマゾンで買いました(・∀・)
今日からこれをメソッドチェーンならぬ参考書チェーンと名付けて実践していこうと思います。この時、注意する事は、戻り値を1つにすること。そうしないと参考書ツリーになってしまって、スタックに積まれてしまう(((( ;゚д゚)))

アジャイルサムライ−達人開発者への道−

アジャイルサムライ−達人開発者への道−

初めてのアジャイル開発 ?スクラム、XP、UP、Evoで学ぶ反復型開発の進め方?

初めてのアジャイル開発 ?スクラム、XP、UP、Evoで学ぶ反復型開発の進め方?

実践アジャイルテスト テスターとアジャイルチームのための実践ガイド (IT Architects' Archiveソフトウェア開発の実践)

実践アジャイルテスト テスターとアジャイルチームのための実践ガイド (IT Architects' Archiveソフトウェア開発の実践)

「プログラマが知るべき97のこと」を読んで

プログラマが知るべき97のこと」を読んで。

先日、名古屋アジャイル勉強会に参加した為か自分の中で読書熱が高まってきました。そんなこんなで上記の本を読んだ感想です。

まず、この97のことシリーズの特徴は、何といっても視点がとても多い事。普通の○○(数字)のこと系の本だと、一人の視点から書かれている事が多いけどこの本は色々な人が、重要だと思う事を書いているので一つ一つのコラムがバラバラの事を書いているのに良いバランスになっていて良い感じ。

いくつもの良いコラムがあったのですが、その中から気になった一つを紹介。マーカス・ベイカーさんが書いていた「最初が肝心」のコラムです。大分端折るとソフトウェアへの入り口は分かりやすくといった内容?だったと思います。

これは、最初の導入方法が分かりやすくないと結局使われないよ。と言った事で最初に触れた製品が自分の要求に合っていて簡単に導入出来たなら、他のライバルとなる製品がたとえ最初に触れた製品より優れていたとしても乗り換える人は少ないよと言ったお話でした。

確かに僕もAndroidに換えた時にカレンダーと天気予報のアプリをインストールしたけど、これと言って不満が無いので他のアプリを探すことすらしていません。それどころか友人にお勧のアプリとして紹介することもあったり--;

分かりやすくて、導入しやすい。これは、ソフトウェアに係わらず商品を選んでもらう重要な要素。この事からも一期一会の考え方はとても重要だなと思った次第・・・。明日から出来るだけ心掛けるようにしたいところw

最後に、「プログラマが知るべき97のこと」はプログラマとして飯を食べて行こうと思っているなら読んでおいて損はない本だと思いました。オススメです^^

プログラマが知るべき97のこと

プログラマが知るべき97のこと