ざざっとメモ。
Middlewareの種類
一口に Rack middleware と言っても目的とする動作にはいくつかバリエーションがある。
- request を処理する middleware
- response を処理する middleware
- その他を処理する middleware ( middleとは? )
例えば Rack::Access や Rack::Cors, OmniAuth はアプリに到達する前の request を処理する middleware であり、Rack::ETag や Rack::Deflator は response を処理するものである。ExceptionNotification などはその他を処理する middleware である。
基本的にアプリは適当でよい
例えばこんな感じだ。
- 適当な lambda を作って名前を付ける(#callを呼べればなんでもよい)
- rspec や minitest/spec では let でもよい
この時に大事なのは、例外を起こす lambda にするか、あるいは期待する値を返す lambda にするかなど、「気にしていることだけを実現する lambda」を雑に作ってしまってよいということだ。Rails アプリであろうがなかろうが Rack middleware のレベルでは status code と headers と body の三つが揃っているというただそれだけのものになる。
テストしたいアプリをbuildする
テストしたい middleware を use してテストしたい条件の lambda を run するアプリを build する。
Rack::Builder.new do
use Middleware
run Application
end
これを call すれば Rack middleware のテストは行える。
テストで気にするものについて十分なパターンを用意する
- request を処理するなら env のパターンが豊富になる1
- response を処理するならアプリの lambda をいくつも用意する
- その他の場合も恐らくアプリの lambda の準備を厚くする形になるだろう
例えば ExceptionNotification のようなものをテストしたいのであれば
Rack::Builder.new do
use Middleware
run lambda { |env| raise StandardError }
end
みたいなものが必要になる。
参考
request の path や何らかの header について該当するかしないかのパターンを用意することになるはずだ。 ↩
CoffeeScript を軽く試してみようと思ってあれこれ調べているうちにたどり着いた Middleman というツールを紹介してみる。
Middleman: Hand-crafted frontend development
たぶん試したのは 2.0.3 だか 2.0.4 だかその辺。
特徴
- Sinatra based ( つまり ruby 製 )
- Sass 自動コンパイル
- CoffeeScript 自動コンパイル ( Sprockets を使った依存性解決も )
- Sinatra で使える view の機能
- HTML テンプレートは erb, haml, slim, markdown が利用可能
- YAML で「データ」を持ってこれを view に反映できる
- livereload 対応
そして、静的サイトとして出力できる。
利用技術
- CoffeeScript
- Sass
- EventMachine
- Thin
- Guard Livereload
など、お馴染みな人にはお馴染みなもののオンパレード。
あと Ruby はたぶん 1.9 の方が良い。1.8 でも動くかもしれないけど、自分はうまくいかなかった。(後日ちゃんと動いたので大丈夫かも。)
インストール
gem install middleman
残念ながら EventMachine や Thin の辺りが native extension なので Windows ではややこしい。(あ、Mac でも XCode 入ってないとまずいです。)これらの gem にはそれぞれ Windows 版があるんだけど、なぜか Middleman がうまくそれらを利用できない。
gem 自体は全部入ってるのでうまくやれば使えそうな気はするんだけど、勇者募集中らしい。
Twitter / @middlemanapp: If you're a Rubyist on Win …
使い方
初期化から実行
middleman init PROJECT_NAME
cd PROJECT_NAME
middleman
とすると middleman server が立ち上がるので、
http://localhost:4567/
にアクセスして簡単な紹介文が表示されれば ok.
デフォルトではこんな感じでファイルができる。
PROJECT_NAME/
├── config.rb
└── source/
├── images/
├── index.html.erb
├── javascripts/
├── layout.erb
└── stylesheets/
└── site.css.scss
静的サイト生成
project のディレクトリで
middleman build
とすることで
build/
というディレクトリができてその中に生成済み HTML, JavaScript, CSS, そこから利用するファイルが配置される。
build 以下を Web サーバ配下に置けば静的サイトの公開終わり。
画像とかどこに置けばいいの?
middleman server が動いている状態なら
source/
の中の構造がそのままブラウザで確認できる。例えば index.html.erb の内容が http://localhost:4567/ に表示される。変換しないファイルも同様。
エンジンは拡張子で
init したばかりの状態で .erb と .scss があるのでなんとなく分かると思うけど、何を使うかは拡張子で指定する。例えば
source/javascripts/application.js.coffee
を置けば
http://localhost:4567/application.js
でコンパイル済みの JavaScript ファイルにアクセスできる。CoffeeScript を使わない場合は .js の拡張子でそのまま JavaScript を書けばよい。
index.html.erb じゃなくて index.html.slim を置けば slim を利用できる。
レイアウトの変更
config.rb を見ればまず分かると思う。その中から二つだけ取り出して紹介しよう。
template と layout を別々のエンジンで
set :markdown, :layout_engine => :slim
こうすれば
...
└── source/
├── images/
├── index.html.markdown
├── javascripts/
├── layout.slim
...
のように個々の文書は markdown で、layout を slim で書くことができる。
特定のディレクトリ以下の layout を全部変更
with_layout :layout_mobile do
page "/m/*"
end
こうしておくと上の設定と合わせて
...
└── source/
├── images/
├── index.html.markdown
├── javascripts/
├── layout.slim
├── layout_mobile.slim
├── m/
│ └─ index.html.markdown
...
こんな形で layout ファイルを分離できて、
http://localhost:4567/m/
以下はモバイル専用といった形で利用できる。スマートフォンであれば JavaScript が利用できるので、redirect を諦めれば静的サイトでも両対応サイトは十分実現可能だし、Middleman を使えばそのために2倍の HTML のコーディング量を要することもない。
YAMLデータを使ってコンテンツの使い回し
ここから先はまだ実際には試してないのでコード例は出せないけど、上の layout の切り替えに加えて
- YAML に複数行データでコンテンツを持たせる
- markdown などのルールから変換して HTML として展開
することで HTML のコーディングだけでなくコンテンツも再利用できると思う。
いずれ試してみたい。
その他
- livereload でブラウザに切り替えて reload することなくファイルの変更を反映可能
- ただし WebSocket を利用するのでブラウザを選ぶ
- JavaScript や CSS の minify
- Y! Smush.it を使った画像の最適化
などもできるらしい。ほんとになんでもアリだなぁ。
参考
livereload は昔からよくあるブラウザを自動でリロードするやつのモダンな実装。WebSocket を使うので 2011-08-10 時点では Firefox, Chrome ともに拡張を入れる必要がある。
- LiveReload - Chrome ウェブストア
- LiveReload :: Add-ons for Firefox
- Railsアプリを変更したら自動でブラウザをリロードしてすぐ確認できる guard-livereload|WEBデザイン Tips
- Firefox 6.0+ でそのままで使えずにしばらく悩んだ。対応バージョンに注意。
最近は Mac のネイティブアプリ化に向けて頑張ってるらしい。完成したら「terminal で gem 入れて」とか何ゆってんの?な人でも使えるようになって面白いかも。
要求
OSX 10.4 で Google Calendar をブラウザを使わずに利用したい
正確には iCal のカレンダーを共有したい、だったんだけど、関係する人みんなの見れるサーバが必要だけど、それだったら Google Calendar 使った方がいいんじゃないの?ということでそっちの流れに。
選択肢
OSX 10.5 以降は標準で iCal が Google Calendar と同期できるらしいんだけど、10.4 では標準ではできないらしい。10.4 で現実的なのは
- Thunderbird + Lightning + Provider for Google Calendar
- iCal + GCalDaemon
くらいっぽい。
自分が使っているのが Lightning だったので 1 の方法をオススメした。
Thunderbird + Lightning + Provider for Google Calendar
- 無料メールソフト Thunderbird – Windows 7 対応メールソフトの決定版
- Lightning :: Add-ons for Thunderbird
- Provider for Google Calendar :: Add-ons for Thunderbird
Provider for Google Calendar を入れると「新規カレンダー」を作成する際に「ネットワーク上のサーバに保存する」の中に「Google カレンダー」という選択肢ができるので、そこに ICAL フォーマットのカレンダーアドレスを追加すれば ok.
public な calendar でも認証を要求されるみたい。まぁそのくらい我慢しろということで。
iCal + GCalDaemon
Tape » iCalとGoogleカレンダーの同期(OSX10.4の場合)
から辿った方法で実現できるらしいんだけど、今回は試してない。
あらためて書くほどたいした話じゃないです。
細々した仕事をするスクリプトの多くは基本的に sh スクリプトが多いと思うのですが、やはり sh スクリプトでは多少荷が重い仕事もあります。awk や sed などを使うのはまぁ常套手段ではありますが、あんまり激しくコマンドを呼び出すとそれだけ負荷が高くなっていきます。そういう場合、自分は Ruby で書き直してしまうのですが、すでに稼働中の sh スクリプトを含めて毎回同じような設定を書いていることに気がつきました。わずか数行の代入文とは言え、なんかこれ無駄な感じがします。
sh スクリプトの変数代入は基本的に以下のように書きます。
VAR=VAL
自分の場合、sh スクリプトの変数は常に大文字で書くようにしているのですが、よく見たらコレ、
Ruby の定数定義と同じじゃん
と気づきました。しかも Ruby はバッククォートを使った別プロセスの結果の取得も sh スクリプトと同じように動きます。つまり、特別なフォーマット(XML やら YAML やら)を用意しなくても、特別なパーサを用意しなくても、同じ設定をそのまま sh でも Ruby でも読み込むことができるということです。
具体的にやることは以下のように、
- 変数定義の部分を別ファイルに切り出し
- sh スクリプトでは . で 1 のファイルを読み込む
- Ruby スクリプトでは load で 1 のファイルを読み込む
だけです。
Ruby の方で定数はちょっと扱いにくいなぁと思ったら Object.const_defined?(), Object.const_get() を使って変数に取り込むことも可能です。
最初から小文字で変数を書いて Ruby でもローカル変数として取り込めばいいじゃんという意見もあるかもしれませんけど、Ruby スクリプト側は恐らくコードと設定の分離を意識して書きたいだろうから、ローカル変数にいきなり取り込むよりいったん定数で取り込んでおいて、それを必要に応じて使えるようにしておいた方が気持ちいいような気がします。で、この処理を module に追い出してしまえば毎回書く必要もありません。うん、いいアイディアだ。
※ psh はログインシェルまでこなせちゃう shell です。Perl をインタラクティブに使いたいという、当初の目的からは外れそうです。
川o・-・)<2nd life - perl でインタラクティブなシェルを実現する perlsh
とか見て入れてみっかーと思って Debian etch(4.0) で似たような感じの名前を探してみたところ、
$ apt-cache search readline | grep perl
libenv-ps1-perl - prompt string formatter
libterm-readline-gnu-perl - Perl extension for the GNU Readline/History Library
libterm-readline-perl-perl - Perl implementation of Readline
librarieslibterm-readline-zoid-perl - Pure Perl implementation of Readline libraries
てな感じ。でもやはり perlsh コマンドとやらはインストールされない。cpan から入れているわけじゃないし、ソース展開して deploy なんていやなのねんと思い、気分を変えて FreeBSD の方で
$ make search key=perlsh | grep ^Path
Path: /usr/ports/shells/perlsh
キター。ここで Makefile を読むと
MAN1= psh.1 \
pshcomplete.1 \
pshconfig.1 \
pshdevel.1
おや? psh ?
改めて
$ apt-cache search psh | grep perl
libpdf-api2-perl - provides the functions for creating PDF documents in Perl
psh - interactive shell with the power of perl
おっ。
apt-get install psh
$ psh
psh% File::Glob::<TAB>
AUTOLOAD bootstrap
GLOB_ALPHASORT bsd_glob
GLOB_BRACE constant
GLOB_CSH csh_glob
GLOB_ERROR doglob
GLOB_NOMAGIC glob
GLOB_QUOTE import
GLOB_TILDE
おぉ。豪快に補完される。
ステキ。
※ OSX 10.3 + PPC の環境では cpan からインストールしたあとに .cpan/build/psh-1.8 内で make install した。これで合ってるのかどうかよく分からないけど動いてる。Term::Readline::Gnu はコンパイルにコケるので、Term::Readline::Perl にした。
あーれー? なんか普通のコマンドも補完するな。んー? なんか思っていたのと違う?
OSX では command + tab でアプリケーションの切り替えはできるんだけど、一つのアプリで複数のウィンドウを開いていた場合にそれらのウィンドウの切り替えをキーボードから行うことはできない。
と、思い込んでいたができた。
10.3 の環境ではここで書いてあるのと違って
command + `
だった。ただし、Realforce + WinK ドライバ + uControl の環境では Shift + @ で入れる ` ではダメで、たまたま [半角/全角] に割り当てられていた ` を使ったら動いた。つまり、
command + `
command + tab
はキーボードで縦に並んでる状態になって、予期せずなかなか使い勝手のよい状態に。へー。
23:10 熱闘甲子園 (休止時、以降繰り上げ)
なんて記述を見かけた。げー。繰り上げの可能性あるんだ。なんか埋めろよ。
野球ってのは本当に迷惑なスポーツだなぁ。
紹介されている本を夏休みの宿題にしようかなと思った〆切り前。
うーん、そんなものがあるとは。(まだちゃんと読んでないけど。)ちょっと遊びでこのサイトにも Apple Store アフィリエイト入れてみようかななんてことを考えていたのだけど、これは目に付くチャンスなのか?(違
putty core の security fix に対応。これ書いている時点では日本語版はまだ 3.6.6 だけど。3.6.6 でも対応しているみたいなんだけど、せっかくだから 3.6.7 まで待つか。
サイト全体のテイストを合わせるためにまず選んだのが Hiki. サイドバー対応に will をカスタマイズして、おーなかなかいい感じじゃーんと思っていたが、Hiki が必要としている strscan は shared library じゃないか。Ruby 1.6.8 な aaa cafe で動かそうってのはちょっと無謀だろうと思ってやめる。
VikiWiki を試してみる。相変わらず setup の意味が分かりにくいのと、認証を none にしても必ず認証が必要な予約ページが存在している。この不整合さはどうだ。コンセプトは悪くないと思うのに、どうしても使い始めるに至らない困った Wiki だ。
最終的には FreeStyle Wiki Lite に落ち着いた。FreeStyle Wiki が tDiary テーマコンパチなのは知っていたが、肥大している感じがどうしたものかと思っていたんだけど、FreeStyle Wiki のサイトに行ってから Lite の存在を思い出した。あーこんなもんでいいじゃないか。別に気張ったドキュメント書きに使うわけじゃないんだし。
ということで ぶくまく を用意してみました。ありがち具合がいい感じです。
mail-archives/ を除いて全部 wget したところ、1.8GB に! まぁでも Linux ディストリビューション丸ごと落としたと思えば CD 3枚なのでこんなもんなのか。もう少しインストール/アップデートが速く手軽にできるんなら丸ごと落とさなくていいのになぁ。