ページ

2012年12月17日

リファクタリングとかで作業ブランチを分けて作業して後でmasterにmergeするにはGitではどうやればいいかの説明 - branch, checkout, merge

7ヶ月前に、たった5つのコマンドで今すぐGitによるバージョン管理を始める方法なんて記事を書いた。この記事ではgit init, status, add, commit, logを紹介した。

今回はbranch, checkout, mergeを紹介しようと思う。利用シーンの想定としては、リファクタリングや新機能の開発などでブランチを分けて作業し、一通りうまくいったらmasterブランチにmergeするというイメージ。

バージョン

筆者のMacで使ってるGitは1.7.12.1で、最新安定版は1.8.0.2あたりだったはず。持ってない人はgit-scmからダウンロードしてインストールしてください。

はじめに


まずmasterブランチ(最初からあるブランチ)で適当なファイルを作成してコミットしておく。

branch

いわゆるブランチを一覧したり、新規作成したり、削除したりするためのコマンド。Subversionなどと違って、ブランチを切るたびに新しくディレクトリが作成されずに、同じディレクトリ内でGitが自動的に切り替えをしてくれる。

新しくtestingブランチを作成する。引数なしでgit branchとすればブランチの一覧が見れる。
現在選択中のブランチには*が付く。

checkout

ブランチを移動するコマンド。
-bオプションを付ければブランチの新規作成と移動が同時に行われる。

merge

ファイルの内容を変更してコミットする。
testingブランチに移動していたので、このコミットはmasterブランチではなくtestingブランチで行われた。masterブランチに戻ってソースを確認してみれば、変更が元に戻っていることが分かる。
masterブランチへtestingブランチをmergeさせる。
mergeによってファイルがtestingブランチの最新コミットに更新された。

git logしてみれば分かるように、masterのコミットにはマージコミットが作成されずにtestingのコミットがそのままつなげられる。これをfast forwardingといい、変更が競合(衝突、コンフリクト)しない限り、最新のコミットが適用される。

mergeのオプションを付ければ、必ずマージコミットを作成したり、コミットを一つにまとめてmergeしたりすることもできる。

おわりに

人に質問されてブランチやマージについて答えたので、そのついでにブログを書いてみようと思ったけど、やっぱり文章だけで説明するのは難しかった。もっと分かりやすい説明をしている記事やスライドがあるので、それを紹介して終わります。


2012年11月18日

東京Node学園祭2012に参加して


今日は東京Node学園祭2012に参加してきた。講演者や運営の皆様、お疲れさまでした。

プログラミング言語やライブラリなどのカンファレンスに参加したのは実は初めてで、とても刺激的な一日だった。今後勉強したい課題もできたし、がんばらねば。

意外だったのは、ハードウェアを利用したアプリケーションの発表が複数あったこと。脳波でミニ四駆的なものを走らせたり、音声認識したり、LEDを光らせたり、風船を膨らませたり。自分もやってみたい。

もし来年もあるなら、今度はもっと実力を付けた上で参加したい。そもそもNode.jsはほとんど触ったことがなかったので、Nodeでアプリケーションを作ってみた上で参加すれば学びもより大きかったのかもしれない。最近本業で忙しかったとはいえ勿体無いことをした。

ま、Nodeで何かをつくりたいという意欲が増しただけでも一日投資した価値があったかもしれない。やるぞー!


んで、当面の学習の方向性としては、Node.jsをしっかりと自分のものにしたい。特にアプリケーションの分散や、Stream周りの効率化など。

もう一つはNoSQLで、前々から勉強しようと思いつつも後回しになってしまっていた。特にJSON形式のドキュメント指向データベースを勉強したい。

勉強に役立ちそうなリンクもまとめておく。

2012年9月20日

インターネット概論 〜どうしてつながるの?〜

あなたのスマホ、PCどちらを使っても構わないので、アメブロにアクセスしてみてください。

どうやってアクセスしましたか?ブラウザのお気に入りから?検索して結果からアクセス?アプリを使いました?URLを入力して直接アクセスした人もいるかもしれません。

ここでちょっと考えてみてください。当たり前すぎて気付いてないかもしれませんが、今起こったことは簡単に説明できることではありません。

どうしてつながるの?

なぜブラウザやアプリで、求めていたものが表示されるの?

今回はインターネットを支える基本の考え方、インターネットで商売をしていく上で最低限の知識となるものを紹介していきたいと思います。

いきなり結論を書いてしまいますが、今日のインターネットを支えるものは次の3つです。

  • サーバー
  • クライアント
  • ネットワーク

サーバーはユーザー情報や画像など、あらゆる情報を持っています。サーバーにはたくさんの種類があり、メールを受け取ったり、ブログのサーバーならユーザーの投稿を管理したり、情報を持つだけでなくそれぞれが様々な役割を担っています。

クライアントはWebサービスにアクセスするためのデバイス(パソコンやスマートフォン、タブレットなど)です。ブラウザ(SafariやFireFoxなど)からサーバーにアクセスし、サーバーとうまくやり取りをしつつ、受け取ったデータから画面を構築していく役割を担っています。

ネットワークはインターネットそのものといっても過言ではありません。サーバーどうしをつなぎ、クライアントが目的のサーバーにたどり着く手助けをします。

来週社内で非エンジニア向けにインターネット概論の講座を開講しますが、質問やワークを交えながら、こういった話をしていこうと考えています。

内容をもっと噛み砕いて、分かりやすく詰めていかないと。

2012年8月25日

1行で動くFizzBuzzコード.rb

研究が進まなくて気付いたらFizzBuzz書いてた。

FizzBuzz

これからWebデザインの勉強を始めるのに役立つ書籍・資料まとめ 2012年度前期版

Patrick Gage cc
Webデザインの経験がない同期のデザイナーに、これからどうやって勉強していけばいいのかを聞かれ、良さそうな本を紹介してほしいといわれて紹介した本のまとめです。

そのときには紹介していなかった、オンライン学習サイトやモバイルUI/UXに関する書籍も追加しました。

プログラマ・エンジニアの人はこちらもどうぞ
2013新卒のWeb系エンジニアが実際に読んでいるプログラミング入門書籍まとめ

1. よくわかるHTML5+CSS3の教科書

Webに関わるなら、どんな職種であろうと絶対に避けて通れないのがHTMLとCSSに関する知識。この本は決して網羅的ではないけど、全体を把握するには十分な情報量で、よく整理されているので初めて勉強するには非常にオススメしています。

よくわかるHTML5+CSS3の教科書

2. すべての人に知っておいてほしいスタイルシートデザインの基本原則

よくわかる~でHTML+CSSの基本に目を通しただけだと、たぶん自分の作りたいイメージ通りのデザインを表現するのは難しいと思います。
この本にはパターン的に実際に現場で使われるようなデザインの表現方法が説明されているので、CSSをさらに詳しく丁寧に学びたいならオススメです。

すべての人に知っておいてほしい スタイルシートデザインの基本原則

3. Web標準の教科書

次に紹介するのは、まさにスタンダードというような本。かつて、これを読んでないHTMLコーダーは素人といわれた(嘘)。
2008年の本で情報が古い部分もあるのでざっと目を通すくらいでいいと思いますが、Web技術者(クリエーター含む)は教養として読んでおいた方がよいです。辞書的に使うのがいいのかな。

Web標準の教科書―XHTMLとCSSでつくる“正しい”Webサイト

4. Codecademy

HTMLをCSSを使いこなすと、いわゆる静的ページというものを作ることができるようになります。マウスを乗せると色が変化したり、レイアウトを整えたり、ボタンのデザインをかっこよくしたり、といったことですね。でも、フォームなどからの入力を受け付けて、サーバーで処理をして、データベースとやりとりをして…というような動的に変化するページを作ろうとするとプログラミングが必要になってきます。

クリエーターはサーバーサイドプログラミングはしないにしても、フロントサイドのJavascriptプログラミングくらいはすると思います。Javascriptを使えばCSSだけではできなかったような表現もできるようになります。(ブラウザゲームとか、フォームの入力チェックとか)

Codecademyというオンライン プログラミング学習サイトを使えば、Javascriptというプログラミング言語の学習をすることができます。無料です。
最近ではPythonやRubyのベータテストも始まっているので、少しずつほかの言語も対応してくと思います。

Webに関わるならHTMLやCSSを避けて通ることはできないと言いましたが、JavascriptもWebプログラミングをやっていくなら避けては通れない言語です。

Codecademy


5. JavaScript本格入門

Javascriptの入門書。Javascriptの入門書でいいのはあんまりないんだけど、しいていうならこれかな。でも、プログラミングをまったくやったことないという人には難しい気がするし、結構プログラム書いてきてる人には足りない感じです。プログラミング経験者でJSを始める人は下のパーフェクトJavascriptがいいかもしれません。
JS初学者向けの良書がないかと薦められたので追記しました。

JavaScript本格入門 ~モダンスタイルによる基礎からAjax・jQueryまで

6. パーフェクトJavascript

これは良書です。このブログでも既に何度か紹介していますが、Javascriptの勉強をしっかりやるなら最良だと思いました。一番のお気に入りの本です。サイ本より好きです。この本を読んでJavascriptが大好きになりました。

…プログラミング初学者には薦めませんが一応紹介。

パーフェクトJavaScript

7. iOSヒューマンインターフェイスガイドライン

PDFです。Appleが無料で公開しています。iOSアプリケーション向けですがモバイルUI/UXについて勉強になる資料で、iOSに限らず他のモバイルアプリケーションの開発にも役立つと思います。無料なので読みましょう。

iOSヒューマンインターフェイスガイドライン[PDF]

8. すべての人に知っておいてほしい スマートフォンサイトデザインの基本原則

これもスマートフォンデザインのUI/UXに関する書籍です。2で紹介したスタイルシートデザインの本と同じシリーズですね。最近出たばかりです。Web系のIT企業各社の開発最前線で活躍しているクリエイターたちが執筆していて、実際に直面する事例を基にした内容になっています。スタイルシート編と同様、良書です。

すべての人に知っておいてほしい スマートフォンサイトデザインの基本原則

まとめ

一番最初に勉強すべきは、HTMLです。HTMLが一番重要です。これが分からなかったら文字通り話にならないです。その次がCSSで、CSSをある程度勉強したら(1と2の本を読破するくらい)、HTMLとCSSだけを使って世の中にあるWebサイトをそっくり真似して作ってみるのが良いと思います。(Webデザイン講座とかでも行われたりしています)

俺もJavascriptとUI/UXの勉強がんばろう!

2012年7月22日

Windowsのコマンドプロンプトでlsコマンドを使えるようにするための最も手っ取り早い方法 ※ただしCygwinは除く

Windowsはクソですね。いや、WindowsもすごくいいOSだと思いますよ。
ただ、この環境で開発しろと言われるとがっかりしちゃうのも事実。

Eclipseは最強のIDEだし、気に入らなければNetbeansというIDEもなかなか素敵です。(自分はNetbeans派です)

ただ、Windowsの最もクソたらしめている要因は2つあると思っていて、1つはコマンドプロンプトの貧弱さにあると思っています。
もちろんCygwinもありますが、これ、微妙じゃないですか?/cygdrive/c/ってなによ。

Cygwinを使うくらいならVMでLinux MintなりUbuntuを使う方がマシです。メモリさえ許せば。


本題。


コマンドプロンプトでlsコマンドを使うにはどうすればよいか。
自分がやったのは、cygwinのバイナリファイルが置いてあるところへパスを通しただけです。
こうすることで、コマンドプロンプトでもlsや他のUNIXコマンドが使えるようになります。

CygwinでUNIXコマンドを手に入れて、コマンドプロンプトを使うのが現状ではベターかなって思ってます。

Windowsのコンソールについて、他により良い案があれば教えてください。(切実です)
コメントでもtwitterでも意見お待ちしてます。

2012年7月9日

変数の存在とプロトタイプ: Javascriptを本格的に勉強し始めて驚かされたこと その2

nyuhuhuu cc
Javascript (JS) の勉強会に行ってきました。今週で4週目(第4回)です。第2回のときもそうでしたが、今回も驚きや新しい発見があったのでブログにまとめておこうと思います。テキストは引き続きこれを使っています。


パーフェクトJavaScript (PERFECT SERIES 4)

1. 変数の存在チェック(ReferenceError例外の発生を修正する)

宣言していない変数から値を取り出そうとするとReferenceError例外が起きる。この例外を回避する方法を挙げていく。
// 遅延評価を利用する
var a = a || 7; // aが既に値を持っていれば変数aの値を使う(イディオム)

// aが厳密にundefiendかどうか調べる その1
var a; // 既に定義されている場合は値はそのまま変わらない
var b = a !== undefined ? a : 7; // aが既に値を持っていれば変数aの値を使う

// aが厳密にundefiendかどうか調べる その2
if (typeof a !== 'undefined') {
  var b = a;
} else {
  var b = 7;
}

// aが宣言済みか(存在するか)を調べる
if ('a' in this) {
  var b = a;
} else {
  var b = 7;
}

2. new式の挙動

コンストラクタは以下のように書く。
function MyClass(x, y) {
  this.x = x;
  this.y = y;
}

これをnewしてオブジェクト(インスタンス)を生成する。このときのnew式の動作は以下のようになる。
  • 空のオブジェクト{}を生成する
  • new式で指定した関数(コンストラクタ)を呼び出す
  • this参照がオブジェクトのプロパティとなる
この挙動はあたかもクラス定義からインスタンスを生成しているように見えるが、Javascriptにはクラスという概念はない。ただ、コンストラクタ(関数)からnew式によりオブジェクトを生成しているだけである。ただ、Javaなどのクラスベースの言語を使っている人からすると、クラスを定義してインスタンスを生成していると考えた方が分かりやすいかもしれない。

3. フィールドとメソッドを持つクラス定義

Javascriptにはクラスはないけれど、コンストラクタ(関数)によりフィールドとメソッドを持つクラスのようなものを定義できる。
// クラス定義に相当
function MyClass(x, y) {
  // フィールドに相当
  this.x = x;
  this.y = y;
  // メソッドに相当
  this.show = function() {
    print(this.x, this.y);
  }
}
js> var obj = new MyClass(3, 2);
js> obj.show(); // => 3 2
ただしこのコードには以下の問題がある。
  • このコンストラクタをnewして生成されるインスタンスにはすべて同じshowメソッドが定義されるため、メモリ効率と実行効率がよくない
  • プロパティ値のアクセス制御(privateやpublic)ができない
このうち前者は以下の方法で解決できる。

4. プロトタイプ継承

上のコードには共通するshowメソッドをすべてのインスタンスのプロパティにコピーしてしまうため効率が悪かった。これをプロトタイプ継承を使って書き換えると以下のようになる。
function MyClass(x, y) {
  this.x = x;
  this.y = y;
}
MyClass.prototype.show = function() {
  print(this.x, this.y);
}
js> var obj = new MyClass(3, 2);
js> obj.show(); // => 3 2
このとき生成したインスタンスオブジェクトobjはプロパティにshowを持たないが、prototypeオブジェクトのプロパティshowを継承している。

5. プロトタイプチェーン

パーフェクトJavascriptの138ページにいろいろ説明があるけど、要約するとメソッド呼び出しの優先順位は
  1. オブジェクト自身のプロパティ
  2. コンストラクタのprototypeオブジェクトのプロパティ
  3. さらにprototypeをたどって得たプロパティ
という風になり、最終的にObjectの持つプロパティが実行される(Objectも持たないプロパティの場合はundefinedになる)


2012年6月25日

型変換の挙動とイディオム: Javascriptを本格的に勉強し始めて驚かされたこと その1

nyuhuhuu cc
Javascript (JS) の勉強会を初めて2週目(第2回)にして言語仕様に驚かされることがたくさんあったため、まとめておこうと思います。ちなみに使っているテキストはこれです。


パーフェクトJavaScript (PERFECT SERIES 4)

プログラミング経験がない人は絶対に読むべきではないですが、他の言語でプログラミングの経験がある人がJavascriptを新たに勉強するには非常にオススメできるかなり良いテキストです。そう感じました。

同じ専攻の同期4人で勉強を進めていて、とりあえず初めから読んでいこうということになり、先週は1-2章を読み、今週は3章「Javascriptの型」を読み進めました。

ちなみに実行環境はFirefoxのWebコンソールやChromeのJSコンソールを使って対話的に行っています。
FirefoxはSpiderMonkey, Chromeはv8と処理系が異なるため、微妙に挙動が違うこともありますが、本ではSpiderMonkey準拠なので、Firefoxで試す方が良さそうです。

FirefoxのWebコンソール
FirefoxのWebコンソール
では本題。

1. 文字列型と文字列クラスの比較

Javascriptには同値比較演算子が2つあり、==と===で挙動が異なる。

var s1 = "abc"; // これは文字列値
var s2 = new String("abc"); // これは文字列クラスのインスタンス
s1 == s2; // => true
s1 === s2; // => false
これは、==が暗黙の型変換をしてから比較するのに対し、===が型変換をせずに両辺の比較を行うところに原因がある。===をstrict equalという。

2. 文字列値の暗黙の型変換

var s = "abc";
s.length; // => 3
"abc".length; // => 3

文字列値sは値、文字列リテラル"abc"はリテラルでありオブジェクトではないのだが、暗黙の型変換により形式上プロパティアクセスをしているように見える。
これと同様の現象は数値クラスでも起こり、文字列クラスや数値クラスをnewする必要性はなくなる。さらばクラスベースオブジェクト指向!

3. オブジェクト型のインスタンスは参照型

こういう現象も起こる。
var s1 = new String("abc");
var s2 = new String("abc");
s1 == s2; // => false
s1 === s2; // => false
s1+'' == s2+''; // => true
s1+'' === s2+''; // => true
文字列の内容は同じでも参照先のオブジェクトが異なるためfalseになる。一方、+''してやると暗黙の型変換により文字列値どうしの比較となるためtrueになる。

4. 文字列値から数値の型変換

数値クラスの関数呼び出しにより数値を得ることができる。
var n1 = Number(1); // => 1
typeof n1; // => "number"
var n2 = Number("1"); // => 1
typeof n2; // => "number"
n1 + n2; // => 2

Number("1x"); // => NaN
parseInt("1x"); // => 1
parseInt("x"); // => NaN
parseInt("0xff"); // => 255
parseInt("ff", 16) // => 255
parseInt("ff", 10) // => NaN
parseInt("0xff", 10); // => 0
parseInt("0.1"); // => 0
parseFloat("0.1"); // => 0.1

5. NaNの挙動

コードは書かないけど、NaNが現れたらどんな演算をしてもNaNになり、同値判定、比較演算も常にfalseが返される。値がNaNであることの判定をするにはグローバル関数のisNaNを使う。
こういった挙動の理由はNaNがNot a Numberの略語であり、「数値ではない」と考えれば何かと足し合わせたり、比較しようとしても結果を定義できないことを考えると理解しやすい。

6. Booleanへの型変換の挙動

これはよく考えると当たり前のものもあるが、驚かされる。Booleanへの型変換はBoolean関数呼び出しで明示的に行え、暗黙的にはifやwhile文の条件式の中で暗黙の型変換が行われる。
// Boolean値はそのまま
var t1 = Boolean(true); // => true
var f1 = Boolean(false); // => false

// 数値は0とNaNがfalseになり、それ以外はtrue
var t2 = Boolean(1); // => true
var t3 = Boolean(-1); // => true
var f2 = Boolean(0); // => false
var f3 = Boolean(NaN); // => false

// 文字列値は空文字列値""以外はtrueになる
var t4 = Boolean("abc"); // => true
var t5 = Boolean("false"); // => true
var f4 = Boolean(""); // => false

// null値、undefined値はfalseになる
var f5 = Boolean(null); // => false
var f6 = Boolean(undefined); // => false
中でもBoolean("false")がtrueになるのは注意したい。

7. nullとundefinedの違い

nullは何も参照していない状態を表すで、null型にはnull値の1つしかない。null値はリテラル値。
undefinedは何も定義されていない状態を表す変数で、undefined型にはnull同様undefined値の1つしかない。だがこれはリテラル値ではなくあくまで変数(読み込み専用)。

8. Javascriptのイディオム

3で書いたような表現はクライアントへの転送量を削減するためのイディオムだったりする。他のスクリプト言語でも普通に使われるようなものもあったが、面白いものがいくつかあったのでまとめてみる。
// 数値から文字列値
var n = 1;
n+''; // 数値1から文字列値"1"への型変換
typeof(n+''); // => "string"

// 文字列値から数値
var s = "1";
+s; // 文字列値"1"から数値1への型変換
typeof(+s); // => "number"

// Boolean型へ
!!1; // => true
!!0; // => false
!!''; // => false
!!null; // => false

// オブジェクト型からBoolean型
// この場合は何を受け取っても必ずtrueとなるので注意
Boolean(new Boolean(false)); // => true
Boolean(new Number(0)); // => true
Boolean(new String('')); // => true
!!1と!!0はすごいと思った。二重否定かぁ。

まとめ

今までクライアントサイドもそれなりに書いてきましたが、ググってコピペしたり、jQueryをこねくり回したりと、Javascriptと真剣に向き合ってきませんでした。このままではいかんと取り組んでみた結果、Javascriptに限らないものもありますが、面白い言語だなぁと感じました。やってみてよかったです。
Boolean("false")やBoolean(new Boolean(false))がtrueになったりと直感に反する部分もありますが、でもよく見てみると論理的で、ほかの動的型付けをする言語とはまた違うなぁという印象です。これからどんどん学習を進めていきますが、また新たな驚きが待っていると思うとわくわくします。この感じはrubyを初めて触ったとき以来かもしれない。非常に楽しみです。

2012年6月19日

Solrのスキーマ schema.xml のトークンフィルタ設定~StopFilterFactory編

Apache Solr ロゴ

solr.StopFilterFactoryとは

テキストファイルに列挙した単語 (ストップワード Stop words) を取り除くトークンフィルタ。 英語圏なら"this", "is", "a", "the"など、日本語圏なら"これ", "は", "です", "ます"などは検索にはほとんど使用されないため、これらの単語をストップワードとして登録し、インデックス作成時やクエリ時に取り除くことでインデックスサイズを小さく抑え、検索単語数を少なくすることで検索速度を速くすることができる。

使い方

ストップワードはテキストファイルに列挙し、schema.xmlと同じディレクトリに保存する。

words属性でstop wordsファイルを指定し、ignoreCase属性で英単語の大文字小文字を区別する (false) か否か (true) を指定する。

<fieldType name="text_jaとかを指定" class="solr.TextField" positionIncrementGap="100" autoGeneratePhraseQueries="false">
  <analyzer>
    <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords_ja.txt" />
  </analyzer>
<fieldType>

ストップワードファイルは例えば以下のように記述すればよい。(1文字のものはLengthFilterFactoryで除外するので記述していない)

あの
ある
あれ
いる
いわゆる
および
かしら
から
くらい
けれど
けれども
こそ
この
これ
さえ
さて
さらに
しか
しかし
する
そして
その
そのうえ
それ
それで
だから
だけ
だけど
だに
だの
ために
つまり
です
では
でも
でもない
ところが
ところで
どの
とも
どれ
なぜなら
など
なので
ならびに
なり
ので
のに
ばかり
ほど
ます
また
または
まで
もし
やら
より

参考

2012年6月13日

Rails 3でCan't connect to MySQL server on 'localhost' (10061) のエラーが出た時の対策

Rails 3開発マシンを新調し、新たな開発環境にRailsプロジェクトをGit cloneして開発をしようとしたら、アプリケーションからMySQLへ接続する際にCan't connect to MySQL server on 'localhost' (10061) というエラーが発生してMySQLへ接続できなくなってしまった。
簡単に解決できたが、なぜこのようなことが起こったのか分からないのが気持ち悪い。

バージョン

  • Rails 3.2.2
  • MySQL 5.5.25

config/database.ymlを以下のように設定する

- host: localhost
+ host: 127.0.0.1

ちなみにhostsの設定でもlocalhostを127.0.0.1へ向けて有効にしていたが、database.ymlをこのように編集しないとうまくいかなかった。謎。

参考

Can't connect to MySQL server on 'localhost' (10061) in Rails 3

2012年5月31日

nohupコマンド - SSHログアウトしてリモート接続を切ってもバックグラウンドジョブを継続して実行させる

nohup
photo credit: brnzwngs via photo pin cc
サーバーでスクリプトやバッチジョブを実行するとき、バックグラウンドで実行していてもSSHの接続を切ると停止してしまう。
何日かかけて実行する場合や、プログラムを継続的に実行したい場合にはnohupを使うとよい。

nohup java -jar batch.jar &

nohupを使ってプログラムを実行し、&をつけてnohupをバックグラウンドで実行する。
nohupを実行するとホームディレクトリ ~/ にnohup.outが作られ、そこに標準出力やエラー出力が書き込まれる。

ジョブを停止させたいときはps -xなどで実行中のプロセスを確認し、kill (プロセス番号) すればよい。

バージョン

  • CentOS 6.2

参考

2012年5月23日

自分でビルドしたApacheにPhusion Passengerを導入する方法

Phusion Passenger

Phusion PassengerをApache上で動かすにはpassenger-install-apache2-moduleを使うと簡単に設定ができる。これはすごく便利だが、通常のyumでインストールしたApacheがデフォルトで選択されることになる。そうではなく、自分の用意したRPMやソースからビルドしたApacheに変更するにはどうすればよいか。

バージョン

  • CentOS 6.2
  • Apache 2.2.22
  • ruby 1.9.3
  • gem 1.8.24
  • passenger 3.0.12

Apacheを指定する

Passengerはgemでインストールして、passenger-install-apache2-moduleでコンパイル・設定するのが簡単でいいと思うけど、自分の用意したApache上で動かすにはパスを指定してからpassenger-install-apache2-moduleを実行する必要がある。

指定するパスはApache2とApache2 development headersの2つ。一時的にexportで指定してやればよい。

gem install passenger
export APXS2=/usr/local/apache/bin/apxs
export PATH=/usr/local/apache/bin:$PATH
passenger-install-apache2-module

これでできるはず。

参考

Apache上でRuby on Railsアプリケーションを動かす/Passenger(mod_rails for Apache)の利用

2012年5月9日

YAML形式のfixtureファイルの書き方

photo credit: Ezu via photo pin cc
Railsアプリケーションの開発において、データベースの初期化を行うためにはseedファイルを使うかfixtureファイルを使う方法がある。今回はfixtureファイルを用いたデータの初期化を想定し、fixtureファイルの適切な書き方を説明したい。

書き方によっては問題なくfixtureされるのに、実際にはデータが入らないということもあるので、そのあたりも解説したい。

バージョン

  • ruby 1.9.3
  • rails 3.2.2

基本の書き方

authorsテーブルとauthor_idを外部キーに持つbooksテーブルがあるとして話を進める。

authors.yml
shun_tak:
  name: Shun Tak

dave:
  name: Dave Thomas


books.yml
ruby:
  title: プログラミングRuby 1.9
  author: dave

tech:
  title: 開発日誌
  author: shun_tak


一つのブロックが一つのレコードを表し、レコードを識別するラベル(shun_tak: , dave: など)の下位レベルに「フィールド名: 値」の形式で記述する。注意点として、
  • インデントはタブ文字ではなく空白(一般的には半角スペース2個)で表現する
  • フィールド名: の後には半角スペースが入る
という点に注意する。

外部キー

外部キーは「モデル名: 参照先のラベル」の形式で表現する。上の例でもsubmitterにはsubmitter_idではなく、submitterに対応するラベルが記述されている。
Railsアプリケーションではデータ作成時に、idをauto incrementせずにRailsの機能が自動で番号を付ける。ラベルによる関連付けを行う場合も同様で、特にidを明示する必要はない。(明示してもよいが)

ラベル名の制約

レコードごとに付けるラベルだが、数字のみだとデータが挿入されないようだ。特にエラーが出力されないのでしばらく原因が分からなかったが、ラベルの数字を文字列を含むように変えたら解消されたので、これが原因だと思われる。

参考

2012年5月8日

ActiveRecord::AssociationTypeMismatch errorの対策

Ruby on Rails ロゴ
外部キーのあるモデルのビュー周りで、ActiveRecord::AssociationTypeMismatch errorが発生した。書籍やWebで調べてもぴったり同じ解決法がなかったので、記事として残しておく。

今回実装したかった機能は、外部キーを持つReportsに対してCreate, Read, Updateの機能を実装すること。

難しい実装じゃないはずなんだけど、Railsに慣れていなかったせいか苦労した。これからもっと勉強して実装経験を積んでいかないと、自分のRailsのレベルは実戦には程遠いだろうと感じた。

バージョン

  • ruby 1.9.3
  • rails 3.2.2

データベース定義

ReportsテーブルとSubmittersテーブルがあり、以下のように定義されているとする。

テーブル名Submitters
物理名データ型NullDefault備考
idintegerNoPRIMARY KEY
AUTO INCREMENT
namestringYesNull
created_atdateNo
updated_atdateNo

テーブル名Reports
物理名データ型NullDefault備考
idintegerNoPRIMARY KEY
AUTO INCREMENT
titlestringYesNull
submitter_idreferencesYesNullFOREIGN KEY
created_atdateNo
updated_atdateNo


Create & Update

とりあえずコードから。

reports_controller.rb (抜粋)
def new
  @report = Report.new
  @submitter = Submitter.all

  respond_to do |format|
    format.html
  end
end

def edit
  @report = Report.find(params[:id])
  @submitter = Submitter.all
end

def create
  @report = Report.new(params[:report])

  respond_to do |format|
    if @report.save
      format.html { redirect_to @report, notice: 'Report was successfully created.' }
    else
      format.html { render action: "new" }
    end
  end
end

def update
  @report = Report.find(params[:id])

  respond_to do |format|
    if @report.update_attributes(params[:report])
      format.html { redirect_to @report, notice: 'Report was successfully updated.' }
    else
      format.html { render action: "edit" }
    end
  end
end


_form.html.rb
<%= form_for(@report) do |f| %>
  <% if @report.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@report.errors.count, "error") %> prohibited this report from being saved:</h2>
      <ul>
        <% @report.errors.full_messages.each do |msg| %>
          <li><%= msg %></li>
        <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :title %><br />
    <%= f.text_field :title %>
  </div>

  <div class="field">
    <%= f.label :submitter %></div>
    <%= f.collection_select( :submitter_id, @submitter, :id, :name ) %>
  </div>

  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>


new.html.erb
<h1>New report</h1>

<%= render 'form' %>

<%= link_to 'Back', reports_path %>


edit.html.erb
<h1>Editing report</h1>

<%= render 'form' %>

<%= link_to 'Show', @report %> |
<%= link_to 'Back', reports_path %>

Read

とりあえずコードから。

reports_controller.rb (抜粋)
def index
  @reports = Report.all

  respond_to do |format|
    format.html # index.html.erb
  end
end

def show
  @report = Report.find(params[:id])

  respond_to do |format|
    format.html # show.html.erb
  end
end


index.html.erb
<h1>Listing reports</h1>

<table>
  <tr>
    <th>タイトル</th>
    <th>提出者</th>
    <th></th>
    <th></th>
    <th></th>
  </tr>

<% @reports.each do |report| %>
  <tr>
    <td><%= report.title %></td>
    <td><%= report.submitter.name if report.submitter %></td>
    <td><%= link_to 'Show', report %></td>
    <td><%= link_to 'Edit', edit_report_path(report) %></td>
    <td><%= link_to 'Destroy', report, confirm: 'Are you sure?', method: :delete %></td>
  </tr>
<% end %>
</table>

<br />

<%= link_to 'New Report', new_report_path %>


show.html.erb
<p id="notice"><%= notice %></p>

<p>
  <b>Title:</b>
  <%= @report.title %>
</p>

<p>
  <b>Submitter:</b>
  <%= @report.submitter.name %>
</p>


<%= link_to 'Edit', edit_report_path(@report) %> |
<%= link_to 'Back', reports_path %>



解説

後で書く。

まとめ

…。

2012年5月2日

solr-rubyを用いてRailsアプリケーションからSolrでの検索を実行する方法

RailsアプリケーションからSolrの検索ができるようになったので、まとめておく。
Apache Solr

バージョン

  • Apache Solr 3.5.0
  • solr-ruby 0.0.8
  • ruby 1.9.3
  • rails 3.2.2

コード

今回はいきなりコードを載せてみる。solr-rubyはGemfilesで読み込むようにしている。
# coding: utf-8

require 'solr'

class SearchController < ApplicationController
  def initialize
    @solr = Solr::Connection.new( 'http://localhost:8983/solr', :autocommit => :on )
  end

  def index
    data = submit(params)
    numFound = data['response']['numFound']
    docs = data['response']['docs']
    
    # テンプレートにレンダリングするなり適当に処理する
  end
  
  private

  def submit( p = {} )
    query = p[:q]
    filter = p[:fl]
    start = p[:start]
    rows = p[:rows]
    query = '*:*' unless query
    filter = 'id,score' unless filter
    start = '0' unless start
    rows = '10' unless rows
    
    select = Solr::Request::Select.new(nil, { 'q' => query, 'fl' => filter, 'start' => start, 'rows' => rows } )
    @solr.send(select).data
  end
end

コードの解説

今回はRailsの解説ではないので、Solrとのやりとりの部分を解説する。

まず3行目。ここでSolrモジュールを読み込む。このgemのソースは簡潔に書かれているので、何かあればソースを読むといい。というか、solr-rubyに関する情報がほとんどないので、ソースを解読するしかない。7行目でSolrとの接続をする。localhostとポート番号は適宜変更する。

続いて30-31行目。Solrとの接続が確立されたら、Selectクラスをnewし、Solrにqueryを発行する。newするときの引数でハッシュを渡しているが、ここでSolr検索時のパラメータを指定する。どんなパラメータがあるかはSolrのチュートリアルなどを参照するとよく分かる。

11行目で返ってきた検索結果を保持する。solr-rubyではXMLをハッシュにして返してくれて、自分でパースしなくて済むのが助かる。ハッシュなので、12-13行目のようにすれば結果を取り出せる。あとは好きなように処理すればよい。


2012年8月24日追記
Gistにもサンプル載せました。ほぼ一緒です。


参考

2012年5月1日

たった5つのコマンドで今すぐGitによるバージョン管理を始める方法

git - the fast version control system

Gitの使い方を簡単にレクチャーする機会があったので、こちらにもまとめておく。主要なコマンドは5つくらいなので、すぐに覚えられるはず。凝った使い方はこの記事の範囲外ですので悪しからず。

この記事の目的としては、とりあえずバージョン管理に触れてみるということと、ローカルで完結させるということ。

バージョン

筆者が執筆中のWindowsに入っているgitのバージョンは以下の通り。
  • git 1.7.9

0. Gitをインストールする

Git本家のサイトからGitをダウンロードしてインストールする。
http://git-scm.com/

Windowsだったらhackって書いてないやつでUnicodeって書いてあるやつがいいと思う。
Macなら新しいやつを選べばいいと思う。
Linuxユーザーは自分で考えてくださいな。

以下Windows環境ならコマンドプロンプト、Macならターミナル.appを使って作業します。いずれにせよGitのプログラムディレクトリへのパスは通しておいてください。Linuxは以下略

1. Gitリポジトリを作成する init

ワーキングディレクトリ(例えばworkspace)のプロジェクトディレクトリ(例えばprojectdir)に移動し、"git init"する。コマンドは以下の通り。
$ cd workspace/projectdir
$ git init
これでリポジトリの作成は完了。"ls -a"してみれば(Windowsなら"dir /a")、.gitというディレクトリが作成されていることが分かる。これがローカルに置かれるGitリポジトリで、プロジェクトごとに作成される。.gitを削除すればリポジトリも消える。なので、このディレクトリは触らないようにする。また、このプロジェクトにはtest.plとtest.shというファイルが既に存在していたものとする。
$ ls -a
. .. .git test.pl test.sh

2. プロジェクトの状態を確認し、ファイルを追跡する status, add

次にプロジェクトの状態を確認する"git status"コマンドを紹介する。
$ git status
# On branch master
#
# Initial commit
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       test.pl
#       test.sh
nothing added to commit but untracked files present (use "git add" to track)
これは、test.plとtest.shがGitのコミット予定に含まれていないことを表す。git addコマンドを使うことでこれらのファイルを追跡することができるようになる。
$ git add .
addの後にファイル名を指定すればそのファイルがコミット予定に入り、"git add ."とすれば全てのUntracked filesが追跡対象となる。
$ git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#       new file:   test.pl
#       new file:   test.sh
#

3. リポジトリにコミットする commit

いよいよプロジェクトをリポジトリにコミットする。コマンドはgit commitを使う。
$ git commit -m "first commit"
[master (root-commit) 521c441] first commit
 2 files changed, 23 insertions(+), 0 deletions(-)
 create mode 100644 test.pl
 create mode 100644 test.sh
これで追跡対象のすべてのファイルがコミットされた。-mオプションを付けないとvimが立ち上がって、そこでコミットメッセージを入力することになる。"git status"すると追跡対象ファイルがなくなったことがわかり、コミットログは"git log"で見ることができる。
$ git status
# On branch master
nothing to commit (working directory clean)

$ git log
commit 521c441e339843f7dc08879a1d0a812a380650d4
Author: Shun Tak <shun_tak@windows.pc>
Date:   Tue May 1 20:06:48 2012 +0900

    first commit
このあとは、"git commit -a"とすることで追跡対象のファイルを自動的に検出してコミットしてくれるようになる。新しくファイルを作成した場合は"git add ファイル名"または"git add ."をしてから"git commit"することになる。

ちなみに、-mオプションを付けないで起動するVimは、Vimをインストールしていない場合はGit同梱のものが起動する。すでにインストールしている場合は、通しているパスの優先度順になる。

まとめ

ローカルの開発環境でGitによるバージョン管理を行うには、init, add, commitの3つのコマンドだけが必要なことが分かった。また、状態確認のstatusに加え、コミットログを見るlogコマンドを加えても5つのコマンドだけなので、謎のGUIツールなど使わずにCUIで使ってみてほしい。というかGUIツールの使い方はよくわかりませーん。

リモートも含めたpush, pull, fetchなどや、merge, branch, checkout, stashなど他にも便利かつ必須のコマンドもありますが、そちらの使い方については後日執筆します。

2012年4月25日

RailsアプリケーションでSolrの検索を実行する方法

Apache Solr

バージョン

  • ruby 1.9.3
  • Rails 3.2.2
  • Apache Solr 3.5
  • solr-ruby 0.0.8

solr-rubyを使う

solr-rubyを使うので、Gemfileに以下を追加する。
gem 'solr-ruby'

クライアント側のコード

次のようにすればSolrで検索ができる。
require 'solr'

query = "*:*"
query_param = { 'q' => query }
solr = Solr::Connection.new( 'http://localhost:8983/solr', :autocommit => :on )
select_obj = Solr::Request::Select.new(nil, query_param)
data = solr.send(select_obj).data

結果を得る

dataには検索結果がハッシュで格納されているので、
id = data['response']['docs'][0]['id']
とすれば、一番目の検索結果のIDを得ることができる。

2012年1月29日

私がリモートリポジトリとしてgithubではなくbitbucketを使う6つの理由

Bitbucket
以前Tumblrに簡単にまとめたのを、もうちょっと詳しく書いてみました。(2012年4月27日)

1.5ユーザーまで無料

無料アカウントでも、自分のリポジトリに対して開発メンバーを5ユーザーまで追加できる。5人のうち1人は自分。どのリポジトリをアクセス可能にするかどうかはユーザーごとに選べる。6人以上は有料。
Bitbucket 料金プラン

2.public/privateを選んでリポジトリ作成

Githubでは課金しないとプライベートなリポジトリを作れない。

3.リポジトリはいくつでも作れて、データ容量も無制限

いまのところいくつでもつくれる。

4.GitとMercurialの両方とも使える

分散型のバージョン管理システムとしてメジャーなGitとMercurialの両方に対応している。Gitは当然として、Mercurialにも対応しているのはすごく助かる。

5.https/SSHで通信

HTTPSでPull & Pushできるのは楽。

6.Issue tracking, Wikiに対応

自分はあんまり使わないけど、こういう機能にも対応している。

参考

他にもいろんな機能が充実してきたので、見てみると面白いかも。
Free source code hosting - Bitbucket | Atlassian(日本語)
Bitbucket

2012年1月26日

MacでのRVMを利用したrubyアップデートとRails導入

RVM: Ruby Version Manager

バージョン

  • ruby 1.8.7 --> 1.9.2
  • rails 3.2.2
  • Mac OS X 10.7 Lion

rubyのバージョンを管理しつつアップデートしたい

久しぶりにrubyで開発をすることになり、Macに入っているrubyのバージョンが1.8.7と古かったのでアップデート。少し手間取ったので記録して残しておく。あと、Xcodeがなければ最初にインストールしておいた方がいいかも。

RVMのインストール

以下のコマンドをターミナルから実行してインストールする。
bash -s stable < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer)

設定ファイル

.bash_profileの末尾に設定を追記する。
[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm"
.bash_profileへの変更を反映(ターミナルから以下のコマンドを実行)
$ source ~/.bash_profile

RVMでバージョンの切り替え

これでRVMにインストールされたrubyをバージョンを切り替えて使えるようになる。例えば1.8.7と1.9.2がインストールされているとして、
$ rvm use 1.8.7
とすればrubyのバージョンが1.8.7で動作するようになる。
$ rvm use 1.9.2 --default
とすればターミナルを再起動してもruby-1.9.2で動作するようになる。

rubyをRVMへインストール

次のコマンドでインストールできる。
$ rvm install 1.9.2
1.9.3はなぜかインストール失敗してしまう。原因はあとで考える。
追記:Mac OS X 10.6ではruby 1.9.3もインストールできた。この現象はMac OS X 10.7で起こるタイプのバグかもしれない。解決法を見つけたので後日投稿します。

インストールしたバージョンをRVMでuseしたあと、rubyとgemのパスがRVM内のものに変更されたか確認。
$ which ruby gem

Railsのインストール

最後にRailsのインストールをする。
$ gem install rails
再びパスがRVMにインストールしたものに通っているか確認
$ which ruby gem rake rails

参考

Ruby Version Manager (RVM)(URLがhttp://beginrescueend.comから変更になったようだ)
Macで環境を整えるための環境-homebrewとrvmとrubygems-
Related Posts Plugin for WordPress, Blogger...