RubyJSをためしてたらこんな時間で明日が心配な今日この頃です。
RubyJSはUnderscore.jsやstring.jsみたいなJavaScriptのライブラリです。
特徴はRubyの機能をJSで実装しているところ。JS的な書き方を無視して、以下にRubyらしく書けるかに注力されています。RubySpecに準拠するように書かれているので、Rubyを普段使っている人には無意識に使えるようになっています。
使い方は簡単でライブラリを読み込んで、JSの任意のオブジェクトやプリミティブな値を RubyJS
メソッドを使ってラップしてやります。この RubyJS
メソッドが適切な RubyJS オブジェクトに変換してくれます。もちろん R
というエイリアスが切られているので、こちらを使いましょう。
R 'hoge' #=> RubyJS.String R 1 #=> RubyJS.Fixnum R [1, 2, 3, 4, 5] #=> RubyJS.Array
RubyJS
メソッドで変換された RubyJS オブジェクトには、Rubyでおなじみのメソッドが定義されています。
do (R 'hoge').captalize #=> 'Hoge' do (R 1).succ #=> 2 (R [1, 2, 3, 4, 5]).join ',' #=> "1,2,3,4,5"
また、とうぜんのようにチェインできます。
(R [1, 2, 3, 4, 5], true).map((x) -> x * x).join ',' #=> "1,4,9,16,25"
Enumerable
のメソッドが出てくれば、とうぜんEnumerator
オブジェクトが返ってくるよね。ということでこれももちろん実装されています。
(do (R [1, 2, 3]).each_with_index).map (i, idx) -> [idx, i] #=> [[0,1], [1,2], [2,3]]
map
に自然な感じで関数を渡していますが、RubyのBlockのような使い勝手になっています。といってもふつうのRubyistはmap
を使うときはSymbol#to_procを使うことがほとんどだと思います。以下のように書きましょう。
(R ['1', '2', '3'], true).map R.proc('to_i') #=> [1, 2, 3] # (R ['1', '2', '3'], true).map (x) -> do x.to_i
いくつか注意点があって、Array#include?
のような?
がつく問い合わせ系のメソッドは?
なしで実装されています。また、Rubyには破壊的なメソッドには!
をつける文化がありますが、これは _bang をつけることで再現しています。
(R [1, 2, 3]).include 2 #=> true a = R 'hoge' do a.capitalize #=> 'Hoge' a #=> 'hoge' do a.capitalize_bang #=> 'Hoge' a #=> 'Hoge'
また、+
などのJSの構文とかぶるようなメソッドについては以下のように直接呼びだす必要があります。ちょっとダサいですね。
a = R 'hoge' b = R 'piyo' a['+'] b #=> "hogepiyo"
最後にRubyJS
オブジェクトをJSのプリミティブ型に戻したいときは to_native を呼びます。
do ((R [1, 2, 3], true).map R.proc('succ') ).to_native #=> [ 2, 3, 4 ]
ちなみにR
メソッドの第二引数をtrue
にすることで、配列の各要素を再帰的に RubyJS
オブジェクトに変換してくれます。逆に渡さないと変換してくれないので、ループで各要素を処理するときに、RubyJS オブジェクトが定義しているメソッドが使えなくてはまります。
こんなすてきなライブラリですが、minify しても 20KB くらいあるようで、PCサイトならともかくスマフォ向けのサイトならちょっと迷いどころです。必要なクラスだけ組込めるような感じになるとうれしいですね。
CoffeeScriptのコーディングスタイルは id:hitode909 に準拠しています。(see also: http://hitode909.hatenablog.com/entry/2013/01/20/182349)