トップ 最新 追記

2011-08-01 [長年日記]

_ node replとrlwrap

node.js には repl が標準で付いている。これだけで自分としてはすごく評価が高い。repl 大好き。

で、この repl はまぁイマドキ当たり前だけど編集もできるし履歴も辿れるし補完も効く。

なんだけど日本語の扱いがイマイチ。これはーと思ってたら rlwrap を思い出した。というかそもそも node.js のサイトに rlwrap を使う方法は書いてあったりする。

alias node="env NODE_NO_READLINE=1 rlwrap node"

repl - Node.js v0.5.7 Manual & Documentation

で、試してみた。日本語の扱いはよくなった。やった! でも当たり前だけど補完が効かなくなった。

そっと repl を抜けた。

Tags: JavaScript

2011-08-07 [長年日記]

_ JavaScriptとCSSの構文チェッカ2011

まとめ

npm に便利ツールが揃ってきてる。

果たして JavaScript という言語が構文チェッカに向いているのか自分には分からないんだけど*1、昔と違って全部 JavaScript で済むという環境が本当に揃ってきていて、かつては Perl などで書かれていたツールが今は JavaScript に集約されつつあるみたい。

とりあえず jshint, csslint をうまく使えるようにしていきたい。

背景

ここ数年は Firebug などのブラウザ上の強力なデバッガ、チェッカが活躍する機会が多かったけれども、とは言え

いちいち目的のページを手で開いてチェッカのレポート、あるいは警告やエラーの出ないことをを目視確認するのはバカバカしい

とずっと思っていた。また手動&目視は作業者のレベルに大きく左右されてしまうのも問題。「ちゃんとチェックしてよ」と言わずに済むならその方が嬉しい。言う手間も含めて省力化できるし、漏れも防げる。

手作りの HTML についてはだいぶ前に

簡単なWeb作り向けRakefile作った

なんてものを作って

  • HTML tidy
  • linkchecker

を利用していた*2んだけど、やはり

  • JavaScript
  • CSS

も対象にしたい。もちろん

The W3C Markup Validation Service

はあるんだけど、

  • ローカルだけで
  • できるだけサクっと利用できる

ものが欲しい。ということで改めて探してみると最近は JavaScript 製で揃ってきているみたい。

リスト

JSLint

最初に JavaScript 製のツールがキテるっぽいと思ったのはこの名前を聞いてから。

もちろんサイトが有名なんだけど、

npm install -g jslint

するとコマンドがインストールできる(もちろん今のところ Un*x 系の環境が必要)。

最近 Emacs 22 + js2-mode から Emacs 23 + js-mode に移行したので以前よりチェックが甘くなってしまって IE のバグを踏んで苦しんだのもこれを使おうと思ったきっかけ。

ただし jslint はちょっと不評な面もあるらしい。

JSHint

ということで fork したのがこれ。

同じく

npm install -g jshint

でインストールでき、実行ファイルが入る。これについては

jshint4rというものを作りました

Rubygems で入れられるバージョンを作ってみたので Windows の人も試してみてね。

JavaScript Lint

JavaScript Lint

Win, Mac, Linux 用バイナリがあるんだけど、止まってるっぽいなぁ、これ。

csslint

npm search すればイロイロ出てくるんだなと試して見つけたのがコレ。

あ、今見ると IDEA*IDEA で紹介されてるのか。知らなかった。

動かしてみると selector に ID 使うんじゃないとか言われる。ん? 最近はそういう常識なの? メンテナンス性の項目に入ってるみたい。なるほど…。

JS[LH]int ほどにはこうやって使ってみてる、みたいな日本語記事を見かけないけど、評判はそれなりにいいみたい。   CSSTidy ってのもあって最適化もしてくれるんだけど、今後は期待できそうにないかなぁ。

*1 少なくとも Ecma レベルだと全然機能が足りないと思うんだけど、node.js 環境なら十分便利なのかも。

*2 と言っても実際の利用機会は作った時期から半年程度で今はほとんどないんだけど


2011-08-10 [長年日記]

_ 最新のfrontend技術を使いまくれる静的サイトジェネレータMiddleman

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 ともに拡張を入れる必要がある。

最近は Mac のネイティブアプリ化に向けて頑張ってるらしい。完成したら「terminal で gem 入れて」とか何ゆってんの?な人でも使えるようになって面白いかも。

Tags: Ruby Web

2011-08-13 [長年日記]

_ CoffeeScriptのコンパイル方法とか資料を調べてみた

大ざっぱにまとめ

  1. browser で直接コンパイル
  2. coffee-script.js を利用して手動でコンパイル
  3. 自動で watch してコンパイルして serve してくれる便利フレームワーク

くらいの方法があるみたい。

browser で直接コンパイルして実行

とりあえず動かす分にはこれでも大丈夫。本家ドキュメントにもしっかりこの使い方は書かれている。

コマンドラインでコンパイル

npm の coffee コマンドでコンパイル

browser で直接コンパイルして実行するのは遅いので事前に .js に変換したい。そういう場合は npm で

npm install -g coffee-script

でインストールできる

coffee

コマンドを使うのがいちばんの王道。

Windowsの場合

2011-08-13 現在 Windows では npm は動かない(node.exeはある)ので、他の方法を考える必要がある。

CoffeeScript on Windows? - Stack Overflow

だいたい以下の方法に落ち着くみたい。

  • WSHを使う方法
  • 海外では jsdb.exe が比較的人気?
  • 日本では NILScript が比較的人気?

具体的にはこの辺。

CoffeeScript-Compiler-for-Windows は本家からも参照されている。

ruby からエンジンをいい具合に選んでコンパイル
  • ruby をすでに使っていて
  • gem が使えて
  • なんらかの JavaScript エンジン(含む node.exe)は入っている
  • しかし npm は使えない

この場合は、わざわざ別途 JavaScript エンジン付きのコンパイラをインストールする必要はない。以下の gem を利用すればそのとき使える適当な JavaScript エンジンを利用してコンパイルしてくれる。

josh/ruby-coffee-script - GitHub

こいつは本家の Rakefile にある coffee-script-source gem を利用している*1ので、上に挙げたような独自コンパイラ実行環境を使うよりは、古いバージョンを使い続ける可能性が少し低いので安心かもしれない。

使い方は以下のような感じ。

ruby -r coffee-script -e \
  'puts CoffeeScript.compile( open("/path/to/script.coffee"), opts )' \
  > /path/to/dest.js

Windows の cmd.exe だとこう。

ruby -r coffee-script -e \
  "puts CoffeeScript.compile( open(\"/path/to/script.coffee\"), opts )" \
  > /path/to/dest.js

node.exe が入っていればちゃんと Windows でも node.js を利用してコンパイルしてくれる。

自動でコンパイルしてほしい

毎回手でやるのは面倒くさいしばからしい。

npmが使えるなら
coffee --watch

で ok

Rubyなどのいい具合にしてくれるフレームワークを利用する

あくまで Web 上での利用でとにかく楽をしたい場合は上のコードを透過的に実行してくれる

  • Rails 3.1+
  • Middleman

なんかがオススメ。

どっちも Windows には厳しいけど。

CoffeeScript でテストを書く

mhevery/jasmine-node - GitHub

とかで利用できる。

素の jasmine は rspec に比べるとだいぶしんどい感じなので、CoffeeScript で書けるとかなり嬉しい気がする。そのままだと rake に統合できなかったりブラウザでテストしたい場合とか考えると Rails プロジェクトなんかだと逆に面倒かもしれないけど、昨今の JavaScript の応用範囲の広さはハンパないので、いろんなシーンで検討の余地はありそう。

資料

文法など
その他の環境など

本家の情報がだいぶ充実してる

*1 CoffeeScript の開発には Ruby が使われてるわけです


2011-08-14 [長年日記]

_ rack-legacyを試してみようとしてMacではダメだった件

Ruby, RubyGemsの制限

  • rack-legacy 0.3.0 は本当は RubyGems 1.8 以降対応
    • bin/rack_legacy が Gem::Specification.find_by_name を使っているから
  • rack_legacy コマンドを使えば内部の rack_legacy.ru を使ってくれるので、require とか use とか run とか自分で書く必要なし。アプリのある場所でいきなり叩けば ok
  • Ruby 1.8 でも 1.9 でも動く

PHPの制限

`php-cgi` を呼んでいるので

  • PHP 5 以降*1
  • Mac 標準の PHP では動かない(入ってないから)

※ php-cli と php-cgi とバカ正直にバイナリを分けなきゃいけないもんなんだろうか。php-cgi という名前で呼び出されたら CGI 用のモードで動く、とかできそうなもんだけど。

使ってみようとしたんだけど

実は Mac では Apache + mod_php の環境はすぐに動かせるんだけど、

  1. システム全体で Web サーバが動いてる必要は全然ない
  2. PHP のコードを書くときだけ軽く動かせればよい
  3. いちいち VirtualHost の設定とかしたくない
    • 本来そんなもの必要ないはずなんだけど、しておかないと PATH が変わってしまう
  4. システム全体にライブラリを突っ込んでいって汚すのもイヤ

と思ってる。

そこで rack-legacy を使えないかなと思ったんだけど、上の php-cgi で躓いてしまった。他のバージョンは知らないけど少なくとも OSX 10.5 標準の PHP には CGI バイナリは入っていない。それだけをインストールする方法もない。MacPorts などで PHP を丸ごと一式入れ直す方法もなくはないけど、それだったら MAMP 入れたり VM で Linux 入れてしまっても手間的には大して変わらない気がするというか、Linux 入れてしまう方が構成的に最も素直だと思う。どうせ本番環境は Linux なんだから、それに近い方がトラブルは少ない。

実際、入れてあった CentOS 上には php-cgi はあったので、こっちでやった方が楽そうだ。問題は VM を動かすのは「少しも手軽じゃない」ってことだけ。

ということで見送りになってしまった。うーん残念。本格的に受け入れテスト用の環境として使うなら rack-legacy + RSpec よりは Cucumber になるんじゃないかなと思うし、面白いんだけどちょっと使いどころが難しい。

Tags: OSX PHP Linux Ruby

*1 本物のレガシーをなめちゃいけない


2011-08-16 [長年日記]

_ OSX10.5 + Ruby 1.9.2 + sqlite3 gem 1.3.4が入らない

T/O

1.3.3 なら入る。そういうもんなのかな。

Tags: Ruby SQLite

2011-08-17 [長年日記]

_ Rails.envは全体に影響するけど、RSpec書いてて忘れちゃった話

[2011-11-20 追記] stub を使えば戻し忘れの問題はないみたい。こんでいいのかな?

Rails 3.0.10 + RSpec 2.6.0 のお話。

すごく当たり前なんだけど、RSpec の block で区切れる書き方を見慣れてたら忘れてしまっていたこと。

Rails.env 変更したら spec の実行全体に影響します。

そらそうだ。

ダメな例

具体的には

module FooHelper
  def bar
    if ( Rails.env.production? )
      ...
    end
  end
end

こんな感じのヘルパーメソッドをテストするために

desribe FooHelper do
  context 'production' do
    before {
      Rails.env = 'production'
    }
    it {
      bar.should == baz
    }
  end
  context 'development' do
    before {
      Rails.env = 'development'
    }
    it {
      bar.should == qux
    }
  end
end

なんてことをしてたんだけど、他のspecが落ちちゃう。なんでかなーと悩んでたんだけど、何のことはない。

 after(:all) {
   Rails.env = 'test'
 }

で戻しておきましょうっていうだけだった。

もう一度。

そらそうだ。

stub にするのが正解かな?

stub にすれば block 内だけ変更されるみたい。自分の場合は RR を使っているので

stub(Rails.env).production? { true }

とすれば本番環境用の動作に切り替えることができる。これであれば RSpec の作る block 内でだけ影響するみたい。少なくとも戻し忘れて他の spec が落ちるような動作はしないように見える。


2011-08-18 [長年日記]

_ Kaminari 0.12.4とwill_paginate 3.0.0がconflictするらしい

環境と現象

中まで深く追ってはいないんだけど、以下の環境でサイトが動いてて、

  • Rails 3.0.x
  • 管理画面に Typus 3.0.x
    • Typus が will_paginate に依存している
  • front の方は Kaminari を採用している

will_paginate 3.0pre2 のときは正しく動いていたけど、will_paginate 3.0.0 に上げると Kaminari の動くところが根こそぎダメ

という現象が起きる。

逆に Typus 側というか will_paginate 側は問題は発生しない。

二刀流の経緯

すでに Typus で will_paginate が動いているにも関わらず、front の方に Kaminari を採用したのは will_paginate の(当時の)放置っぷりと「Kaminari は見た目のカスタマイズ楽だよ」という話に乗ったから。

もちろんちゃんと両方問題なく動くのは確認してたんだけど、pre2 が正式リリースになった時点で conflict するとはちょっと予想してなかった。

解決方法

今のところ

  • Gemfile で will_paginate は pre2 で止めておく

ことで対応している。で、実は

  • Rails 3.1 対応の Typus 3.1 系では Kaminari が採用されている

ということでこの問題は Rails 3.1 に上げると全部解決することが分かっているので、あとは時期と作業ボリュームの問題だけになっている。

そのうちやる。

Tags: Rails Ruby

2011-08-20 [長年日記]

_ .rvmrcの扱いを明示するrvm rvmrcコマンド

.rvmrc っていう、そのファイルの置いてあるディレクトリに cd した瞬間にそこで指定された ruby がデフォルトで実行されるバージョンになるっていう超絶便利な機能があります。

分かりにくいですね。例えば

rvm use 1.9.2 --default

して普段は 1.9.2 を使っているんだけど、あるプロジェクトの開発をするために

cd ~/Sites/project

すると自動的に ruby -v が REE になる機能です。便利でしょ。

で、これ、勝手に有効になってる時期があったんですけど、いつからか「この .rvmrc 信用して ruby の version 変更していい?」って聞かれるようになりました。なったのはいいんですけど、不用意に「あとで」って N で答えると二度と有効にならない、という状態になってしまいました。

こりゃ困ったなと思って help を読んでいて見つけたのが

rvm rvmrc

です。

rvm rvmrc {trust,untrust,trusted,load,reset} [optional-path]

こういう風に使うそうです。例えば今いるディレクトリの .rvmrc をすぐ有効にしたい場合は

rvm rvmrc load

で、今後ずっと有効にしたい場合は

rvm rvmrc trust

というわけですね。

rvm rvmrc trust && source ~/.zshrc

みたいな方法でもいいかもしれませんというか、自分はそうしました。単に load を知らなかったからですが。

Tags: Ruby

2011-08-21 [長年日記]

_ HTMLかどうかの判定にbodyだけでなくheaderも使う話

※ 実際には8月22日のできごと。

あるテキストデータが HTML かどうか(プレインテキストでないかどうか)を判別する処理の話で、

Hpricot を使っていたときはこう書いていた。

d = Hpricot( src )
d.inspect.include?( 'elem' )

これは Hpricot が

{elem {elem ...

って感じで要素の階層構造を表現してくれることに依存してるんだけど、あまりに乱暴かつ Nokogiri の場合はそっけなく

Nokogiri::XML::Document

だということしか分からないのでどうしようかと思っていた。で、どうしようって Twitter でつぶやいて返事をもらった瞬間に、

どうせ open-uri で取得したものなんだからメタデータで判別すればいいじゃん

と気づいたので、

.meta['content-type']

で確認するようにしてみた。これなら Hpricot か Nokogiri かに関わらず使える。うむ。なんて簡単なことだったのだ。

というわけで実際にできたのはこれ。

Commit 0ce737eb55f968a22f143244a3e7fbf8adf0d34f to wtnabe/pukiassist - GitHub

中身だけで判断しなければいけなくなったときが来たらそのとき考えよう。ちなみに、 /<html/i で判別する方法もなくはないんだけど、データの中に入ってくる可能性もあるかと思って却下としました。ないかもしんないけど、心配したくないしね。


2011-08-22 [長年日記]

_ 古いMechanizeスクリプトを少しモダンにする

まずは定義

古い
Ruby 1.8.5 + Mechanize 0.8 + Hpricot 前提のもの
モダン
Ruby 1.9 + Mechanize 1.0 + Nokogiri 前提のもの

Mechanize 2.0 は新しすぎるので手を出しません。

WWW::Mechanize -> Mechanize 変更

Mechanize は 1.0 で WWW ネームスペースがなくなりました。これは機械的に置き換えます。個人的には常に以下のような subclass を用意していたので、この作業はそれほど大変ではありませんでした。

Bundler でまとめて gem のバージョンを管理

gem のバージョンを gem メソッドで指定できることを知って以降、とにかくあの面倒くさい時期の Mechanize に触れないように

gem 'mechanize', '< 0.9'
require 'mechanize'
require 'hpricot'

とかやっていたのですが、個々のファイルでこのように書いていると書き直しや gem のインストールが面倒なので Bundler でまとめてしまいます。具体的には

Gemfile

を用意して、

gem 'mechanize', '< 2'

などとします。で、

bundle install

します。

system の gem を汚さない方法

もし system wide な gem に変更を加えるのが難しい場合*1

bundle install --path vendor

のようにして、変更を加えるコードの場所に gem をインストールします。これ以降の作業は全部

bundle exec ./script

みたいな形で行います。この場合は利用する gem は基本的に全部 Gemfile に書いておく必要があるので、

gem 'rake'

などを書き足す必要があるかもしれません。

最初のネック - Hpricot と Nokogiri の encoding の扱いの違い

  1. Hpricot ベースの Mechanize はパース時にもページの encoding はそのままスルー
    • form や link の検索時には "ラベル".tosjis などのように変換が必要
  2. Nokogiri ベースの Mechanize はパース時の encoding はすべて UTF-8 に統一
    • UTF-8 でコードを書いている場合は form や link の検索時には何も考える必要なし ex) link_with( "ラベル" ).click
    • ただしパース前の Mechanize#page は元の encoding のまま保存されている。

到達したページから何らかの情報を取得したい場合は一度手で UTF-8 に変換しないとややこしいです。特に Nokogiri に渡し直す場合は UTF-8 への変換が必須になります。

Hpricot から Nokogiri に切り替える

  • 何はともあれ全部 UTF-8 化する
# -*- coding: utf-8 -*-
$KCODE='u' unless defined? ::Encoding

を付けて回りましょう。もちろん関連ファイルは全部 UTF-8 に統一します。もうさすがに ja_JP.eucJP な環境はない…ですよね?

  • 文字コード変換をどんどん削除
link_with( :text => 'ラベル'.tosjis ).click
-> link_with( :text => 'ラベル' ).click

これで内部で UTF-8 のパース済みデータを持っている Mechanize と比較的仲良くできます。

恐らく、当初思っていたよりは面倒は起きずになんとかなると思います。

パースに失敗する場合

もっと詳しいところがあるのでどうぞ!

Ruby 1.9 対応

上の作業だけで Mechanize 1.0 + Nokogiri 1.5 に対応できていたら、そのまま Ruby 1.9 に対応できる可能性は比較的高いです。ぜひ rvm などから ruby のバージョンを切り替えてテストしてみることをお勧めします。

ただし、1.9 ではどうしてもうまく動かない場合もあります。(いま実際にそれでハマっているコードも手元にあります。これをどうするかは今後考えます。)

*1 そんなことあるのかな?


2011-08-23 [長年日記]

_ cutagemをrake0.9.0以降に対応させる

なんか deprecated だよっつって gem が作れなかったので調べてみました。

0.9.0 から

Rake::GemPackageTask is deprecated. Use Gem::PackageTask (require 'rubygems/package_task')

だそうです。

cutagemベースの拙作shlauncherなんかも同様ですが、以下のように書き換えると gem package を作ることができます。

-require 'rake/gempackagetask'
+require 'rubygems/package_task'
-Rake::GemPackageTask.new(spec) do |p|
+Gem::PackageTask.new(spec) do |p|

rubygems の方に Gem::PackageTask が追加されたのはなんと 2009-04-15 だそうで、もう2年半前じゃん…。

Tags: Rubygems Ruby

2011-08-25 [長年日記]

_ 条件演算子のべからず2題

よく自分は

( condition )
  ? then
  : else

みたいに条件演算子を使って書いてしまうんだけど、日常的に使う言語の中で Ruby も JavaScript もこの書き方はできない。

正確には

  • Ruby では ? を次の行に下ろすと syntax error なので絶対に書けない
  • JavaScript では ; の自動補完が悪さする可能性があり、JSLint, JSHint などで警告される

というもので、JavaScript では書ける。動作は保証されないけど。

ふむ。


2011-08-29 [長年日記]

_ jQueryMobileとpjaxについて分かったこと分からないこと

一部記法が JSer っぽくなく、Rubyist っぽいですが気にしないでください。HTML 5 関連の話は全然追いつけてないのでちょっと慌てました。

まとめ

beta 3 まで待つ

pjax

pjax とは History#pushState と Ajax の合わせ技のこと

と思っていいのかな。

Ajax を利用しているので伝統的な意味でのページ遷移をせず、なおかつ任意の URI や効果を作ることができるもの。

HTML 5 の History API がなぜ出てきたのかは恐らく

  • 素朴な Ajax は戻るボタンが死亡するのでどうにかして history を残す必要がある
  • location は hash 以外を書き換えるとページ遷移が発生してしまう
  • location.hash の書き換えが history に残るかどうかは実装依存

だから。たぶん。

jQueryMobileとpjax

beta 2

beta2 の段階では # を使った通常の Ajax でリンクを処理することでページ遷移時のアニメーションを実現している。つまり、

pjax は利用していない。

しかしこの方法は

referrer が必ず最初にアクセスしたページになる

という致命的な問題がある。「聞いてないよー」って感じ。最初から Ajax アプリケーションを作っているならそういう風に考えればいいだけなんだけど、jQuery Mobile を使う理由は

Ajax アプリを作りたいからじゃなくて、既存のマークアップへのルールを受け入れる代わりにスマートフォン対応サイトを手軽に用意できるから

だと思うので、この仕様はちょっと受け入れられない。この挙動は「通常の Web」とは明らかに異なる世界だから。

beta 3

2011-08-29 現在で beta 3 はまだリリースされていないけど、

beta 2 の release note にすでに beta 3 で pushState 対応するよ!と言われているので beta 3 では上のような状況とは変わってきます。

ただし対応状況は iOS 5+, Android 2.2+ になるのかな?

で、beta 2 現在どうしたか
$.mobile.ajaxEnabled = false

にしてみた。つまり

アニメーションを捨てて普通の URI を採った。

beta 2 の段階でも自前で URI の書き換えをし続けて通常の遷移のように見せることはまぁできるんだけど、beta 3 で状況が変わるのが目に見えているのでわざわざ凝ったギミックを beta 2 用に作り込むのはちょっとあり得ない判断ですよね。

beta 3 出てから考えます。

iOS 4 対応とか

github で確認したんだけど、iOS 4 では例のアニメーションしないんですね。Android 2.2 では動作するのでそういう判別をしているようです。で、なんでだろうと思ったらこんなものを見つけました。

#3: We could use History.js for cross-browser compatibility - Issues - defunkt/jquery-pjax - GitHub

要するに iOS 4 の WebKit はバグってるから知らん、て感じなのかな。History.js 噛ませばもしかしたら動くかも。試した人いるかな? 自分はまだやってみないけど。

jquery-pjax と URI

ここから先は脱線。

defunkt/jquery-pjax - GitHub

jQuery で pjax を手軽に実現するための plugin があるんだけど、これは

サーバ側は request header の内容を見て返すコンテンツを変える

というアプローチになっている。この方が jQuery 側の処理は軽いし、Rails 的には layout の調整とかだけで十分対応可能

pjaxが便利過ぎて鼻血出そうになった(railsのサンプル付き) - SELECT * FROM life;

で確かに便利そうなんだけど、

Twitter / @komasshu: でもjquery-pjaxがやってるアプローチ(X- ...

とかあって、この辺は実は自分もモヤモヤしてたりする。

一つのURIに異なる表現を割り当てるのはどうなんだろう?

URI 的にも異なる表現*1だということが分かった方がよくないかな。

関連しそうなもの

*1 リソース自体は同一と看做してもいいかなと思うので「表現」にしておく