月別アーカイブ: 2014年5月

Gitでコンフリクトを起こしたくなくて

Gitは分散型バージョン管理システムなので、
ソースコードの同じような箇所を複数の人が修正したら当然コンフリクトが発生する。

コンフリクトを回避するにはマージツールなどを使えばいいんだけど、正直やりたくないのが本音だ。
他人のソースを理解し、そのように採用するか、その作業は思ったより負担になることが多い。
俺の技術不足?それはその通りだ。
でも、それを嘆いてもソースが読めるようになるわけではない。
そこで、コンフリクトを極力起こさないように、ある方法を用いている。

それは非常に単純で、「新規追加機能やクラスは極力別ファイルにする」というものだ。
ファイルが違えば、コンフリクトなど起き得ない。
それに、クラスを別ファイルにすることで、ソース全体への視認性も向上する。

勿論、ソースを見て、ファイルを分けるべきでないなら、分けてはならない。
あくまでTipsなので、それで全体が振り回されるのはいけない。

あ、言うまでもないけど、こんなことしなくてもコンフリクトの原因をすぐに理解し、その修正をすぐに行える人はこんなことすべきでないと思います。
初戦は自分の未熟さをカバーするための回避策です。

なんだこの内容の無さ。

GitHubとBitbucket

世の中ソーシャルコーディングの時代なのか、Gitレポジトリのホスティングサービスが主流になっている。

有名なのはご存知GitHubだが、もう一つ代表的なのにBitbucketがある。
両者ともGitを扱い、PullRequestがあったりと基本的な機能は同じだが、絶対的に違う点がいくつかある。
1)プライベートレポジトリの作成
GitHubは無料プランである限り、プライベートレポジトリは作成できず、常に全世界公開状態ですが、Bitbucketは対照的で、無料プランでもプライベートレポジトリが作成可能です。
ただし、レポジトリにアクセスできるユーザーは最大で5人までという条件があります。
つまり、Bitbucketは大人数での開発には向きません。
個人や少人数で、かつあまり見られたくない開発作業にはドンピシャリです。
2)日本語化
GitHubは完全に英語ですが、Bitbucketは日本語にも対応しています。
多少怪しい日本語ではありますが、誤解が生じないレベルで理解できるので、我らが英語の出来ない日本人には安心感があります。
ただ、一部の日本語が文字化けします。例えばコミットメッセージでよく「実装」という言葉を使っているのですが、これが「実�」と化けます。
まぁ正直、違いは1)に集約される。
SNS的側面を併せ持つGitHubと、あくまでレポジトリのホスティングサービスに徹するBitbucketといったところか。
で、これの使い分けだけど、僕は基本的にはGitHubを使い、見られては行けないコードが含まれているもの(何かのAPIのキーをベタ書きしているコードとか)はBitbucketを使うようにしている。
一時期は全部Bitbucketでやってたんだけど、「人に見られることがない」と思うと平気で汚くてその場しのぎのコードだらけになるんだよね。
GitHubに置いても誰かが見に来ることなんて無いんだけど、「見られる可能性がある」という事実だけで、良いコードを書こうとする意識が働く。
そういうところにこそ、GitHubを使う本当の意味があったりするのかな、と最近思う。
(大体、個人で使うならバージョン管理だけをすればいいから、Gitだけで十分のはずだ)
後、「GitHubを使うとなんかカッコイイ」「GitHubを使っていると、今時のプログラマって感じがする」、という、ミーハーな理由もある。
プログラマでこの先もやっていくとは思えないけどね。
早く帰国して公務員になりたい。

全角半角を区別せずに文字列を比較する。

Dictionary<string,object>のキーについて、ある文字列と全角半角を無視して比較を行おうとしていた。
最初は
Dictionary<string,object> dic=new Dictionary<string,object>(StringComparer.CurrentCultureIgnoreCase);
と設定すればいけるだろうと考えていたが、これでは全角半角は区別してしまうみたいだ。
他のCultureでも同様だ。

仕方ないので、以下のようにやった。

もっと良いやり方があるような気がするのだけど。

結婚式を祝うために

中学時代の友人Tが結婚することになった。

同世代が結婚という大人のステップを進んでいくのに何だか違和感を感じてしまう。
自分の精神年齢が子供のときから変わっていないせいなんだろう。
さて、Tの門出を祝福したいのだが、如何せん海外在住の身。結婚式にも参加できず、とりあえずフェイスブックで式当日にメッセージでも送ればいいか、と考えていた。
しかし先週、突然連絡が来た。それはTの友人で僕の友人でもあるYからだった。
結婚式で流すメッセージビデオ撮って送ってくれない?
無茶である。
しかも期限は来週までと来た。
とりあえず、マーライオンの近くで何かを話そうかな、と。
もちろんふざけたことを話して、最後はなんかいい話風に締めくくり茶を濁すつもりだ。
しかし、具体的な内容は思い浮かばない。
そして動画を撮影する道具もiPhoneぐらいしかない。
更にいうと一人で野外動画撮影、そして撮影被写体として喋るのはキツイものがある。
会社の人に頼むのは絶対に嫌だし、(会社では殆ど喋らないキャラです)
でも残念ながらシンガポールで頼める友達もいない。
あと動画編集もやったことないし。
誰か一人でも協力者がいれば、ずいぶんと違うんだけど。

DataTableの特定の行を別のDataTableに格納する。

「DataTableのある特定の行を抽出し、その結果を格納したDataTableを作る」という操作が必要になった。

何も悩む所は無いと思ったのだが、意外と何回も失敗し、最終的にカンニングをしたので、備忘録として書き記す。

つまり、DataRowはDataTableに所属するオブジェクトなので、
違うDataTableに追加するには全く新しい行を作成して追加しなくてはいけないということ。

もっとスマートにできないのかな。
わざわざSelectしたものをさらにDataTableにするというのがそもそもスマートじゃないのかもしれない。

git rebaseでコミット履歴を修正する

前回メモしたIssueからPullRequestを作成するをワークフローに入れるとある問題が生じる。

それは、空のコミットを作成しているせいで、そのPullRequestをMasterブランチにマージした場合、masterブランチに余計な空コミットが作成されてしまうという点だ。

正直言って、僕は「それでもいいじゃん、変更が追いにくくなるわけでもないし」という考えをしてしまうのだが、会社では可能な限りコミットは綺麗にする方針なので、コミットを修正する方針をとっている。
この変更なのだが、vimが使えないと辛い。
ネットで調べても「vim?使えて当然だろ」と言わんばかりの資料ばかり。
知らないのが悪い、自分で解決しろ、というプログラマのこういうところが嫌だ。
(自分の向上心のなさを棚に上げる)

とりあえず、仕事で使っている最低限のコミット修正、rebaseの使い方を書いていく。


1)commitを行い、pushできる状態にしておく

2)ログを確認し、どのコミットを修正したいか確認する

ex)今回は3番目のfixというコミットを、2番目のwriteというコミットに統合させることを目的とします

3)rebaseコマンドを打ち込む

  • git rebase -i HEAD~(戻る分のコミット数)
  • ex)git rebase -i HEAD~2

4)採用する修正(=最新の修正)のpickをfixupに書き換える

rebaseコマンドを行った途端こんな画面に。
入力する前にキーボードでiを押して入力モードにする。
今回はfixというコミットを採用するので、fixの行をpickからfixupに変更する。
入力したらescキーを押し、コマンドモードに戻る。

5)編集を完了させる

  • コマンドモードで”:wq“と打ち、Enterを押す

6)成功したかgit logで確認

成功。コミットが2つになっている。
“create”コミットの内容は編集前の”create”と”fix”を合わせたものになっている。
リネームが必要な場合は後述参照。

7)成功してれば、pushする。ただし、コミットの書き換えで競合が起こるので、強制pushする

  • git push origin +”ブランチ名”

僕のワークフローでは6)の後、もう一回rebaseでコミット名の修正をしています。
コミット名の修正は”pick”を”reword”として編集完了すればリネーム画面が開かれます。

vim触ったことなかったんだけどメリットが分からない。
どうも、PC初心者です。

第二回電王戦第四局

プログラミングの備忘録ばかり書いていて他のこと書いてなかった。

将棋のこと、でまず最初に思い浮かんだのが、今話題の電王戦。
コンピュータ対プロ棋士というパンドラの箱を開ける戦いで、現在までで3回開催された。
特に印象に残っているのが、第二回電王戦第四局、Ponanza対塚田九段戦。
賛否両論ある戦いなのだが、ドラマという意味ではこれを超す対局は歴史上でもあまりないと思う。
ちょっと説明。
塚田泰明九段はタイトル獲得歴もあり、「塚田スペシャル」という自分の名前を冠した戦法で一時期一世を風靡した強豪棋士です。
塚田スペシャルもそうなのですが、攻めっ気の多い棋風です。
とはいえ、既に50歳近くで全盛期をとうに過ぎ、酷い言い方をすれば「ロートル」という部類になるかもしれません。
(分かりやすく説明するためにあえて失礼な言い方をしています。念のため)
そんな塚田九段がコンピュータと戦う。
「正直言って八割型コンピュータの勝ちだ」と大半の将棋ファンは思っていたと思います。
事実、対局は序盤からじわりじわりとコンピュータが優勢を拡大する展開になりました。
そこで、塚田九段は決意します。コンピュータにただひとつ存在する明確な欠点を突くことを。
そう、入玉狙いです。
入玉狙いの手順が賛否両論を巻き起こしました。
プロ棋士が「正々堂々」でなくコンピュータの欠点を突くということは、既に負けを認めたも同然じゃないか、という話です。
(まず、「正々堂々」の定義が考えるほど分からなくなります。「普通の人間同士の対局と同じように」という意味かと思いますが)
しかし、塚田九段はひたすらに逃走劇を繰り広げます。大駒を全て渡し、それでもただひたすらに相手陣に向かいます。
入玉しても勝ちになるわけではありません。
両者入玉になった場合、駒で決まる点数で勝負が決まります。
塚田九段は既にあまりに多くの駒を渡し過ぎていました。
入玉を果たしてもコンピュータに入玉をされたら点数勝負になり、負けになります。
しかし、先程述べたように、入玉が絡む局面はコンピュータの苦手とするところなのです。
塚田九段はここでコンピュータは入玉をしてこないと読んでいたようです。
しかし、塚田九段が入玉を果たした直後、非情にもコンピュータの玉は塚田陣に向かい始めました。
コンピュータの入玉、それはすなわち点数勝負になり、このままでは負けることを意味します。
敗北を回避するにはただひとつ、相手の駒を取り、引き分けに持ち込めるだけの点数をかき集めるしかありません。
予め断っておくと、人間同士の戦いならこれはまず不可能です。そういった局面でした。
しかし、相手はコンピュータ、インデックスの境界範囲外になればまだ何が起こるかわかりません。
ただ、ひたすらに塚田九段は指し続けました。
それは不毛にも思える時間でした。
実際、このときの控室ではもう対局を中止させようという話が持ち上がっていたそうです。
このままではプロ棋士の権威が無くなる、塚田九段がただ傷付くだけだと。
それを制止したのが塚田九段と同期、この対極の立会人を務めていた神谷七段(現八段)でした。
規定では250手までは指すルールなので、当然の行動ですが、そこには同期棋士としての、信頼があったような、そんなふうに考えてしまいます(後述)。
両者入玉。点数はコンピュータが勝利条件を満たしている。
このまま行けば塚田九段の敗北です。
もはやどれだけ続いたか分からない不毛な指し手の連続に、ニコニコ生放送の解説は段々と茶化したような笑い混じりになってきました。
しかし、ここでとうとうコンピュータに波乱が起きます。
入玉勝負では悪手とした思えない指し手が続いたのです。
とうとうコンピュータは相入玉のこの局面を理解できなくなってきたのです。
惨めな時間がいよいよ報われました。塚田九段は大駒を一枚取り返し、小駒をかき集めます。
そしてとうとう、引き分けに持ち込める局面になったのです。
そこからの様子は下記動画でご覧になれます。

冒頭の木村八段の解説様子からわかるように、終局間際とは思えない笑い混じりの状況です。
見ていた当時は何も違和感はありませんでしたが、今振り返ると異常ですね。
00:20塚田九段が駒を指さして点数カウント。通常の対局ではまず見られない光景です。
03:00-グダグダした確認の後、対局終了。謎の空気。
ここから終始、立会の神谷七段は笑顔です。
この異常な状況に対する単純な笑い、同士のひたむきな指し手が報われた喜び、コンピュータ相手に敗北しなかった安堵、そして対局を止めようとした者達への「見たか」という思いとか、とにかくまぁきっと色々な思いがあったのだと思います。
しかし、その神谷七段も、この異常な状況に酔っていたのかもしれません。
07:15-「投了しようと思ったか」という質問に対し、塚田九段が突然涙する。
そしてその涙を見た瞬間、神谷七段の顔から笑顔が消えます。
神谷七段は同期の塚田九段がここまで戦ってくれて嬉しかった。それは事実だと思います。
ただ、先ほど書いたように、この異常状況で、あることが思考から抜け落ちていたのだと思います。
戦っているのは塚田九段だけだということ。
プライドを捨て、惨めな手を指し続け、その姿を全世界に晒しているのは、塚田九段本人だけだということを。
その計り知れないものの重さを、神谷七段だけじゃない、多分塚田九段を除いた全世界の人が、気付けてなかったのかも知れない。
これほどにまで印象的なシーンは貴重だと思う。
電王戦はこの後も続いているが、ここまでに異常な対局は未だ現れていない。
この対局の話はネット上に溢れてるし、何番煎じかわからない。
でも、将棋と聞いてまず最初に思いついたのがこれなので、素直に書いてみた。
以上、稚拙な文章で失礼しました。

IssueからPullRequestを作成する

hubコマンドで僕が一番使うのがIssueをPullRequestに変更するコマンド。

(っていうかこれしか使わない。極力複雑なことは便利であってもしたくないのです)

理由は仕事でのワークフローがIssueごとにPullRequestを作成して、
レビューを貰ってマージするという方式だから。
正直Issueいらないんじゃないかなって思ってる。
このコマンド、将来的には無くなるらしい。
けど今は使っているので、使い方をメモしておく。

1)PullRequest用のブランチを作成する
  • git checkout -b "ブランチ名"
2)PullRequest作成のためにコミットが必要なので、空のコミットを行う
  • git commit --allow-empty -m "コミットのメッセージ"
3)リモートレポジトリ(ってかGitHub)上にpushする
  • git push origin "ブランチ名"
4)hubコマンドでissueを現ブランチから作成されたPullRequestに変更する
  • hub pull-request -i "Issue番号" -b "ベースにするブランチ名"

以上。
4)の”-b”をずっと”branch”だと勘違いしていた。
“base”の意味だそうです。
2)が必要だったり、このワークフローあまりよくない気がするな。

手元に資料がない状態で書いてるので間違ってるところがあるかも。
資料見て間違ってたら修正します。


追記20140515
2)のコマンドが間違っていたので修正。

追記20140517
言うまでもありませんが、既に変更が加わっている場合はわざわざ2)をする必要はありません。
普通にコミットしてください。
自分のワークフローでは「作業前にプルリクエストを作成する」というルールがあるので、
作業前に空コミットを作成してプルリクエスト作成可能状態にしているのです。

DataTableのFindメソッド

仕事上、.NetのDataTableをよく触る。
主キーが設定されている場合はFindメソッドさんを使えば目的の行を取り出せる。

上記は主キーが”5″である行を取得している。

で、このFindメソッドだけど、どうやら引数の末尾のスペースは考慮しないらしい。
つまり、
dt.Rows.Find(“5”)と
dt.Rows.Find(“5 “)
は同じ結果になってしまう。
回避方法は今のところ不明。
DatatableのSelectメソッドも同様でした。
DataTableの情報には末尾空白のものを持たさないように工夫すべきなのかな。

今日の仕事でここで一瞬詰まった。
コード眺めると何の問題もなさそうだし。
デバッグしたらすぐにおかしいことに気がついたけど、
これは実装中は気付かないなぁ。

調べてみたけどあんまり文献がなかった。常識なのかな。
そういえばSQLのwhere句でも似たようなことがあった気がする。
あんまり覚えていないけど。

Rubyとか知らないけどHubコマンドを導入する方法

GitHubのプルリクエストの作成とか、そういうものをGitBashやコマンドラインからできる凄いやつ、
それがhubコマンドです。
GitHub社製です。

で、こやつはRubyで作られてるらしいんだけど、僕Ruby触ったことないヘボだからよくわからなかった。
試行錯誤して何とか導入したので、とりあえず何をやったかメモ。
絶対に最適方法じゃないけど、「Rubyとか何やねん。Hubコマンド入れたらもうそれでいいねん」という僕と同じ境遇の人の何かの助けになれば。


・前提

  • Windows8.1,Rubyを導入していない
  • GitやGitHubの基本的な作業はできる

1)Rubyのダウンロードページ(https://www.ruby-lang.org/ja/downloads/)に行き、画面最下部の”RubyInstaller”をクリックする。

2)Downloadをクリック

3)RubyInstallersで最新のものをクリックしてダウンロード

  • 2014/05/12時点ではRuby 2.0.0-p481でした。64ビットのやつでも別になんでもいいと思う。

4)インストーラに促されるがままRubyをインストール

  • 途中で3つチェックボックスがある。どっちでもいいと思うけど僕は全部にチェック入れた。
5)インストールできたら続いてhubレポジトリへ(https://github.com/github/hub)
6)hubコマンドレポジトリをローカルにクローンする
  • git clone git@github.com:github/hub.git
7)クローンしたディレクトリに移動し、gem install hubを実行
  • cd hub
  • gem install hub
8)”Successfully installed hub”みたいな画面が出れば完了

以上です。
ちなみに今回はgem install hubでインストールしましたが、これは推奨されない方法です。
他のインストール方法はhttps://github.com/github/hubのREADME.mdに載っています。
ただ、僕はPCリテラシーやRuby知識が「rake?何やこいつ」状態(かつ、調べる時間もなかった)ので、何とかインストールできたこの方法を用いました。
推奨されない方法ですが。
Rubyもやろうって思ってたんだよなぁ。
思ってからもう半年過ぎた。