2012年10月6日土曜日

ブログ移行

JekyllというRuby製のブログジェネレータを使ってGithub Pagesに新しくブログを作りました。ここの記事も今後、Gtihub Pagesに統合していきます。

2012年9月8日土曜日

Asset Pipeline について勉強した

ペパボは今、開発言語をRubyに切り替え始めています。

僕も今、Ruby on Railsを使って開発をしているので、本格的にRuby周りの勉強をし始めているのですが、未だにAsset Pipelineがよくわかってないので、この機会にドキュメントを読んできちんと調べてみました。

参考にしたのはここ。
http://guides.rubyonrails.org/asset_pipeline.html

やっぱり公式のドキュメントが一番わかりやすいかな?自分自身がちゃんと覚えるように読みながらまとめてみました。

Asset Pipelineってなに?


Rails3.1より実装された仕組みで、大きくわけて以下の3つの機能があるようです。

  1. CSSやJavaScriptなどの、いわゆるasset(資源)と呼ばれるファイルを1つにまとめてくれます。普通cssやjsなどのファイルは、開発しやすいように機能毎や画面毎に分けて作業すると思いますが、これはブラウザにとってはファイルの分だけサーバーへのリクエストが発生して効率が悪いです。ブラウザにとっては、ファイルが1つにまとまっていたほうが効率がいいのです。
  2. まとめられたファイルは、同時にミニファイ(圧縮)されます。スペースやタブ、改行などを取り除き、コンパクトに圧縮してくれます。jsファイルに限っては、それだけではなくもう少し複雑なアルゴリズムで圧縮されるようです。
  3. CSSはSASS、JavaScriptはCoffeeScript、を使って記述できます。もちろんSASSやCoffeeScriptを使わずにそのままCSSやJavaScriptで記述することもできます。また、ERB(Embedded Ruby)でも記述できます。
こういった機能がそなわっています。


コードの結合 - マニフェストファイル


まず1つ目の機能の資源の結合について、これはSprocketというgemがあって、そいつがいろいろとよしなにしてくれるわけですが、そのためにマニフェストファイルというものを使います。これは、どのファイルを読みこんで、1ファイルにまとめればいいのかをSprocketが把握するためのものです。Railsでアプリケーションを新しく作った時、app/assets/javascripts/application.jsというファイルがデフォルトであると思います。このファイルを開いて中身を見てみると

//= require jquery
//= require jquery_ujs
//= require_tree .

といった行があります。//=で始まる行はSprocketのディレクティブで、この例では、requireとrequire_treeというコマンドが使われています。名前でなんとなくわかると思いますが、requireは1つのファイルを、require_treeは再帰的にディレクトリ以下の全ファイルを、読み込もうとします。この場合、jquery.js、jquery_ujs.js、それとapp/assets/javascripts/以下にあるすべての.jsファイルを1つのファイルにまとめてくれます。

同じようにapp/assets/stylesheets/applications.cssというファイルもデフォルトであると思いますので、このファイルの中身を覗いてみると

*= require_self
*= require_tree .

こういう行があるのがわかります。cssの場合は*=で始まるんですね。

それから、各ディレクトリのindexという名前のファイルもマニフェストファイルとして読み込んでくれるようです。例えば、lib/assets/library_name/というディレクトリに何かしらのJavaScriptのライブラリがあったとすると、lib/assets/library_name/index.jsというファイルに

//= require_tree .

と書いておけば、そのライブラリに関するファイルを1ファイルにまとめてくれるとのことです。


コードの圧縮 - コンプレッサー


2つ目の機能でコードのミニファイをあげましたが、これは特になにも指定しなくても勝手にやってくれます。ただ、デフォルトの圧縮以外にもCSSやJavaScriptの圧縮機構を自分で指定することができます。app/config/application.rbで

config.assets.css_compressor = :yui

と指定すると、YUI CSS compressorのアルゴリズムを使ってCSSを圧縮します。JavaScriptの場合は

config.assets.js_compressor = :uglifier

と指定すると、uglifierを使ってJavaScriptを圧縮します。また、外部ライブラリではなく自分が開発した独自の圧縮アルゴリズムを指定することもできるみたいです。compressというメソッドを持つクラスを定義して、そのインスタンスを指定します。

まぁこのコード圧縮のアルゴリズムはほとんどの場合、デフォルトから変えなくても問題ないレベルなんだと思います。


コードの事前処理 - プリプロセッシング


3つ目の機能に、CSSはSASS、JavaScriptはCofeeScript、を使って記述できると紹介しましたが、これは拡張子で判断してくれます。たとえばSASSを使ってスタイルシートを書きたい場合は、以下のようなファイル名でファイルを作ります。

app/assets/stylesheets/projects.css.scss

拡張子が.scssになってるのがわかります。これはSASSで処理されて、その結果がブラウザに渡るようになっています。CoffeeScriptも同じで

app/assets/javascripts/projects.js.coffee

とすると、CoffeeScriptで処理された結果がブラウザに渡ります。また、拡張子は複数つなぐこともできて、たとえば

app/assets/stylesheets/projects.css.scss.erb

というファイルがあれば、まずERBで処理されて、その結果がSASSで処理され、さらにその結果がブラウザに渡ります。すげー。


Asset Pipelineの使い方


Rails3.1からは app/assets/、lib/assets/、vendor/assets/ というディレクトリがあります。

  • app/assets/ アプリケーション内で利用する資源を配置
  • lib/assets/ 共通に利用されるライブラリ内で利用される資源を配置
  • vendor/assets/ サードパーティー製のライブラリやプラグインで利用される資源を配置

上記3つのディレクトリ以下にそれぞれ、stylesheets / javascripts / images というディレクトリがあり、その中に実際にCSS、JavaScript、画像を配置します。これらの資源は、Railsでは

<%= stylesheet_link_tag "hogehoge" %>
<%= javascript_include_tag "fugafuga" %>
<%= image_tag "piyopiyo.png" %>

などのようにして呼び出せば、上記3つのディレクトリを検索して、そのうちのどこかに目的のファイルがあればそれを読み込みます。

また、以下のようにマニフェストファイル(app/assets/stylesheets/application.css)を指定した場合

<%= stylesheet_link_tag "application" %>

development環境では結合されずにそのまま複数のファイルで読み込まれますが、production環境になればコードは結合されて1つのファイルにまとまって読み込まれるようになっています。


終わりに


最近Railsをさわってて思いますが、本当に良くできたフレームワークですね。Rubyそれ自体もすごく使いやすくて拡張しやすい言語だと思いますが、その機能をフルに使いこなしたRailsは素晴らしいです。

AssetPipelineについては、他にもFingerprintingやPrecompileなどもあるようなのですが、これはまた別の機会にでも。。。

個人的にはもともとCakePHPを使ってたので、CakePHPのほうが詳しくて、サクサク開発できるんですが、Railsも便利なので、どっちともウォチしていこうかなーと思います。CakePHPもRailsも、これから進化し続けていくことに期待!


2012年8月30日木曜日

jQuery Mobileでscriptタグが2回実行されてハマった

jQuery mobileを使ってると、scriptタグに書いたJavaScriptがなぜか2回実行されてしまって、かなりはまりました。

こんなコードで

<html>
<head>
  :
  :
<script src="jquery-mobile.js"></script>
</head>
<body>
</body>
</html>
<script type="text/javascript">
alert('hoge');
</script>

これだと、最後の行のscriptタグが2回実行されて、hogeというアラートが2回表示されてしまいました。これが何故2回実行されてしまうのかが、まったくわからずに半日くらいはまってましたが、リファレンス読んだら解決しました。

ドキュメント読め俺...

で、解決策はというと

<body>
<div data-role="page">
</div>
</body>

という風に、data-role属性にpageという値を指定してあげると解決しました。jQuery mobileはページ間移動にはAjaxを使い、そのレスポンスをbodyに挿入して現在のページと差し替えます。Ajaxのレスポンスの中にdata-role="page"という属性があると、data-role="page"のタグに囲まれた部分だけを挿入する、という仕組みのようです。

リファレンスを読む限りはこの属性値は通常、ページ毎に配置するように書かれています。


参考
jQuery mobile リファレンス (日本語)

2012年7月27日金曜日

ペパボお産合宿6に参加して

僕が勤めてる株式会社paperboy&co.では毎年『お産合宿』というイベントを開催しています。今年も2012年お産合宿6が開催されました。

どういうイベントか簡単に説明すると、26時間という制限時間の中でチームで協力してサービスやアプリを作り、資料を準備し、プレゼンまでやります。期間内に目標のものを形にできなければ罰ゲームがまっているという、なんだか大変そうなイベントです。
今年でもう6年目になるイベントで、参加人数もなんと過去最多だったそうです!それに張り切ってテーマソングとかまで準備しちゃってます。これはクオリティたけぇ!数秒ですが僕も映っていますヽ(´ー`)ノ

そんなお産合宿6。21(土)、22(日)の2日間で僕も参加してきました。

そして僕らチームポルンガ(5人組)は無事にWellsaidというサービスをリリースしました。


お産合宿
お産合宿はチームで参加します(1人で参加することも出来ます)。僕はなにか作ろうとして、途中で飽きたり、諦めたりして、中途半端で終わることが多いです。でもお産では一緒に頑張っていくチームのみんながいた。それがすごく大きかったとしみじみと思う。チームで一丸となって同じ目標に向かって突き進んでいくことって、こんなに楽しいんだね。


開発はRuby on Railsを使ってやってた。CakePHPはひたすら使ってきたので、ノウハウやコアな部分の理解もあってすごく良く知ってるんだけど、Railsは初めて使う。いくらCakePHPがRailsの思想を取り入れて進化してきたフレームワークだとしても、やっぱり違うところもいっぱいある。RubyとPHPでは文化も違うし、開発中はよく「Rubyっぽくない書き方」だ、って突っ込まれた。

でも、RubyやRailsはもともと興味があったし、チーム内にはRailsマスターがいたので全然苦にならなかった。そして自分が、Railsを覚える速度が異常に早い。やっぱり楽しくやってるとなにもかもが違った。




Wellsaid
Shot! Stick! Wellsaid!

Wellsaidは「うまいこと言うね!」を広げるサービスです。まずはInstagramで認証をしてログインすると、Instagramの写真がWellsaidに取り込まれます。取り込まれた写真は、同じWellsaidユーザーの「誰か」にタイトルを付けてもらうことができます。そしてタイトルをつけられた画像は一覧ページに流れてきて、誰でも見れる状態になるのです。

知らない誰かとコラボして「うまいこと言うね!」を広げていけます。気に入った画像とタイトルがあれば「Wellsaid(うまいこと言うね!)」してください(Wellsaidボタンをクリック)

お産合宿で産まれたばっかり、産まれたてほやほやの赤ちゃんサービスです。まだまだ荒削りなところは多くありますし、改善すべき点、追加すべき機能は盛りだくさんです。また競合もありますので、そことの差別化も図っていかないといけません。

けんたろ社長は言いました。

産むことよりも育てることのほうが大変

まさにそうです!なんとかお産合宿中にリリースまではこぎつけたものの、これからもっと良いサービスにしていくために育てていかないといけない。そのためにはこれまでリリースのために頑張ってきた以上に頑張っていかないと。これからのこのサービスの成長が楽しみです。



ちなみにお産でリリースしたWellsaidは会社の業務としては一切おこなっていません。

2012年7月10日火曜日

CakePHP翻訳会@福岡に参加してきた

2012/7/7(土) CakePHP翻訳祭り@福岡に参加してきました。株式会社Fusicさんが会場を貸してくれました。

参加するまで

こういうイベントに参加するのはとても久しぶりでした。確か最後に参加したのが2年前の第5回CakePHP勉強会@福岡サテライト。その時は、参加して話を聞いて、はい終わり。知らない人ばっかりだったし、たまたまその日は用事があって途中で抜けないといけなくて1人だけ早く帰ったし、んー、勉強会ってこんなものか?って感じ。

で、しばらくこういうイベントには縁がなかった。


CakePHP翻訳祭り@福岡

久しぶりのイベント参加でした。前の記事でも書いたけど、個人的にCakePHPのドキュメント翻訳をやってて、それが福岡で開催されるっていうのと、自分が休みの土曜日にやるっていうのが重なって、久しぶりに参加してみるかーと勢いで参加ボタンをポチっとしました。

当日は会場に一番乗り。誰もおらんかった。。。ぼけー、と待ってたら一気に6人きた!もちろん全員知らん人。前日から翻訳やってた組っぽくて、仲良さげに会話しながら会場に入ってきてせっせと準備開始。その後、追加で1人参加、主催の@cakephperさんが最後にやってきました。

実際、翻訳作業が始まったらみんな結構集中して、ガリガリやってます。僕はConsole And Shells以下を担当。@cakephperさん以外、9人中8人がMacという異常。

1つの場所にみんなが集まってやってるから、ノウハウの共有とかもできて良い感じ。たまに全然関係ない雑談に話がそれたりするけど、それはそれで楽しい。10時半くらいから本格的に翻訳作業が始まって、すぐお昼になって、そしてすぐ夕方になりました。1日が過ぎるのがとても早かったです。


まめちしき

  • rstファイルの行の最後によくあるセミコロン2つ"::"は日本語の後ろについてると、セミコロンが1つ残って画面に表示されちゃう
    • →セミコロンの前にバックスラッシュ&スペースを入れる
  • rstファイル中で改行すると、makeして出来上がったhtmlには、改行したところでスペースが入ってしまう。英語であれば適当な行の長さまできて改行しても、単語間にスペースが入るのは普通なのでいいんだけど、単語間にスペースを入れる習慣が無い日本語では、スペースが入ってしまうと違和感。
    • →行の最後にバックスラッシュを入れる。改行がバックスラッシュでエスケープされてスペースがでなくなります
  • 各rstファイルの最後の方にある:metaってなに?
    • →make htmlした時にできあがるhtmlファイルのmetaタグに含まれる情報のようだ。他言語では存在が消されてる言語もある。消しても問題なさそうなので、今回の日本語翻訳でも消す方針で進めました。
  • content.rstを修正して左側メニューを追加したつもりなのに反映されてない
    • →make cleanしてから、もっかいmake htmlする
  • 日本時間の16時~17時、もしくはそれ以降にプルリクエストしても反応うすいなー。
    • →あっちでは寝てる
  • シェルの履歴たどるのはCtrl+rが便利。意外とみんな知らない。僕も知らなかった。
    • →翻訳に全然関係ない
  • 履歴たどるのはCtrl+pでも超便利だよ。ただしzsh使ってないとダメだけどな!
    • →翻訳に全然関係ない


参加してみて

ひとことでいうと楽しかった。冒頭に書いた2年前の勉強会は、ただ話を聞いてただけだったから、しっくり来なかったんだろう。今回はみんなと一緒に参加した、っていう想いが強かった。実際、みんなと一緒に手を動かして翻訳してたんだもん。大事だよね。

これはいろんなところで言われてることだと思うけど、勉強会とかイベントとかって、ただ出席するだけじゃなくて、参加することが大事っていうこと。それを実感できた日でした。

それともうひとつ。やっぱり知り合いが増えるっていうのも良いことだ。今回、東京にも数名いらっしゃったようですが、福岡には僕の他に8人いました。@cakephperさん、@shin1x1さん、@hiromi2424さん、@msngさん、@BiMihoujyunさん、@suzukiさん、@papettoTVさん、@crownd2さん(順不同)。劇的に仲良くなったかというと、まぁ僕からするとみんな初対面だったしそこまでなかったんですが、一度顔を見たってのが大事だと思ってて、また次どっかで会った時に「あっ、あの時~~~」って話がはずめば、それはそれで楽しい。

今回は個人的に、昔から名前を知ってた人々に会えたのが嬉しかった。自分が知らない世界を知ってる人達もたくさんいる。そういう人達との出会いを大事にしながら、自分も誰かから「あの人と会ってみたい」と思われる人物になりたいですね。

とりあえず今回のイベントは楽しかったです。


終わりに

実はこのイベント中に自分が担当したところをまだプルリクエストしてないという。。。イベント中Macbook Airで翻訳作業やってて、最後は切りが悪いところで終わったので家に帰って続きをしようと思ってたら、諸事情で1週間程度、無線が使えないことを忘れてた。。。これも諸事情だけど、BlueTooth使える機器がないし、USBメモリもないし、どうにもできない!

プルリクエストは最短でも今週の水曜。

翻訳自体はオフラインでもできるので、あとはプルリクエストするだけ!な状態にしとこう。がんばる。

2012年6月20日水曜日

gitのpost-updateフックでブランチ名を取得する

gitでフックする時のお話。

gitの運用で、こんな感じでやる場合があります。

  1. 自分の作業用ブランチで開発作業
  2. 開発が終わったらリモート(中央リポジトリ)にプッシュ
  3. プッシュされたプログラムをデプロイ

2と3の間を自動化するために、post-updateフックなんかを使ったりするのですが、このシェルスクリプトの中でプッシュされたブランチ名を判断して処理したいことがありました。

たとえば、リリース用ブランチ、ステージング用ブランチ、開発用ブランチの3種類のブランチがリモートにあるとして、リリース用とステージング用は、確認してから手動デプロイしたいけど、開発用ブランチだけはプッシュされた後にすぐにプログラムをデプロイしたい、という場合なんか。

で、本題ですが、post-updateフックのシェルスクリプトには、第一引数に完全なブランチ名が渡ってくるようです。

たとえば

git push origin master

としたら、post-updateフックの第一引数には

refs/heads/master

という値が渡ってくるようです。

この値からブランチ名だけを取り出すために以下のようにします。

BRANCH=$(git rev-parse --symbolic --abbrev-ref $1)

こうすることで、$BRANCHの中にブランチ名が入ります。

あとは、この変数で条件分岐などをやればいいだけ。


※参考
http://stackoverflow.com/questions/7331519/find-git-branch-name-in-post-update-hook

2012年4月29日日曜日

vimプラグインをVundleで管理しようとしたときにはまったコト

最近vimに憧れてずっと練習もかねて個人用の環境で使い続けてます。確かに、これは慣れればものすごい作業スピードになりそうな気がしている。。。

ところで、vimには多くの便利なプラグインがあります。僕は今までダウンロードしたプラグインを~/.vimディレクトリにぶっこんでました。今はまだvim始めたばっかりで、そんなに多くのプラグインをいれてなかったので、特に管理なんて意識してませんでした。でもこれからのことを考えると、きちんとプラグイン管理するようにしとかないと、数が増えてきたときに大変になるだろうなーと思って、今はやりのVundleでプラグイン管理してみることにしました。

Vundleのインストールと使い方については、以下のリンクが詳しいです。

Hack #215: Vundle で plugin をモダンに管理する


ここで、前提として僕はFedoraCore15で、vimではなくgvimを使ってました。なので、設定ファイルも~/.vimrcではなくて、~/.gvimrcに書いていました。

で、上のリンクに書いてある通りにやって、Vundleのインストールをして、その後gvimを再起動して:BundleInstallコマンドまではうまくいきました。すげええええ、って思いました。が、その後もう一度gvimを再起動してみたら、さっきインストールしたはずのプラグインが読み込めてませんでした。
(※たとえばunite.vimだったら、:Unite bufferと打ち込んでも、vimのコマンドではありません、みたいなこと言われました)

これ、gvimを起動するたびに毎回:BundleInstallって打てばプラグインが読み込まれて、使えるようになるみたいだったんですが、さすがに毎回そんなことやってられないし、そもそもそんなに面倒くさいわけがありません。ググっても誰もこんなことで悩んでる人がいなさそうだったし、1週間くらい悩んでたのですが、結局なんの情報もみつけることができなくて、みんなこれが普通なのか・・・?って諦めてました。

そんなことがあってたのですが、こないだちょっと間違えて.gvimrcのシンボリックリンクを.vimrcという名前で作ってしまって、まぁ消すのも面倒だったのでそのままの状態にしてgvimを起動しました。すると:BundleInstallしなくてもプラグインが読み込まれてた!

試しに.gvimrcを.vimrcにリネームしてみたら、gvim起動時にちゃんと全部プラグインを読み込んでくれていました。gvimでも.vimrcを読み込みにいくの・・・?そして、.gvimrcだったら起動時にプラグインが読み込まれなかったけど、.vimrcだったらちゃんと起動時にプラグイン読み込んでくれるの?よくわかんない。

とりあえず結果オーライ。。。