2012-02-25

Codeforces Round #109 (Div. 2)

dev

A, B, C, D に挑戦、A, B, D が Pretests を通り、DがSystem Testで落ちた。。

獲得点数は 1202: A=488 (00:06), B=714 (00:34), C=(-2), D=(-2).

A と B はそこそこ読解ゲーだった。

A. I_love_%username%

http://www.codeforces.com/contest/155/problem/A

はじめの読解ゲーがこれ。

まあストーリーな部分から本題を探すのにかなり時間が。

Output を見るに "Amazing performances" の数を出すべきで、 コンテストへの出場履歴の中からそれを数えるみたいな感じらしい。

で、Inputとそのサンプルをみると、1行目がスコアの数 (= コンテスト参加数), 2行目にそのスコアがスペース区切りでくるとある。

そしてまあなにが amazing かというと "amazing in two situations:" という文に続き amazing の条件がかいてある。"more" と "less" が太字になっている。スコアの上下から判断するとみて、とりあえずちゃんと読まずに以下のように解釈した。

  • 前回から成績が下がった
  • 前回から成績が上がった
  • ただし1回目は絶対に amazing ではない。

サンプルをみるにこれだと明らかにおかしいのでちゃんと英文を読むと、 "he earned on each past contest" とあるので、ハイスコアと最低スコアを更新 した時が amazing のようだ。ということで:

  • ハイスコアの更新
  • 最低スコアの更新
  • ただし1回目は絶対に amazing ではない。

これで実装すると sample と正しい動きをするので提出。所要時間6分。

解答: https://github.com/sorah/sorah-codeforces/blob/master/155/a.rb

B. Combination

http://www.codeforces.com/contest/155/problem/B

A は本題を見つけるのが面倒な読解ゲーであったがこちらは 本題がかなりの読解ゲーであった。何が "More formally:" だって感じ。

本題というかやるべき事は 2 段落目に書いてある。3 段落目の More formally らしい文章から先によむと混乱を招いた。

  • プレイヤーはカードを持っている
  • カードの裏表それぞれには 0 を含む正の整数が書いてある
  • カードは使用する事ができ、また同じカードは1度しか使用できない。
  • プレイヤーはまず1枚カードを使用する。
  • カードの表の数値 (a_i) はカードを使用したときにプレイヤーが得られるポイントが書いてある。
  • カードの裏の数値 (b_i) に書いてある分だけ、プレイヤーは追加でカードを引くことができる。

とある。3 段落目をこれを理解したあとによむと「はじめにカウンターが1つで、カードを使用するとカウンターが1つへって、カードの裏面の数値がカウンターに加算され、カードの表の数値がプレイヤーのポイントとなる」みたいな事が書いてあることがわかる。

で、Output はこのルールと指定されたカードだと最大でプレイヤーが取得できるポイントらしい。

解き方としては貪欲法(?)というのか、よくわからんが以下の方法で解いた

  1. カードをまず裏面を優先してソート、裏が等しければ表を利用して昇順ソートする。
  2. 一番最後(一番裏の数値が大きい、または裏の数値が大きくその中でも取得できるポイントが高い)カードを使用する。
  3. カウンターが1以上でかつカードがまだ残っていれば 1 に戻って繰り返す

解答: https://github.com/sorah/sorah-codeforces/blob/master/155/b.rb

C. Hometask

http://www.codeforces.com/contest/155/problem/C

結局解けなかったので解説もうまくできない。 要するに指定された文字列から指定された禁止の二文字を取り除かなければいけない、 文字列からすべての禁止パターンを取り除くには最低で何文字取り除けばいいか、という問題。

ちなみに Ruby でこういうの解くときはなるべく正規表現を使うと高速で素晴らしいです。

D. Colliders

http://www.codeforces.com/contest/155/problem/D

2312 年, n つの加速器が〜、らしいけど飛ばす。

最後の方にある箇条書き、Input などから見ていくと、

  • n つの加速器がある
  • 加速器には1以上n以下の番号がふられている
  • 加速器のオン・オフ命令が Input されてくる
  • オン命令は "+ 番号", オフ命令は "- 番号"
  • オン命令の時、すでに指定された加速器がオンならば "Already on" を出力
  • オン命令の時、 すでにオンになっている加速器の番号と指定された加速器の番号が互いに素 であるときは "Conflist with 指定された加速器の番号" を出力。
  • オフ命令の時、"すでに指定された加速器がオフならば "Already off" を出力
  • オン、オフ命令ともに上記の条件にマッチしない場合は (プログラム内部のオン・オフのフラグを切り替えて) "Success" を出力。

互いに素っていうのが面倒くさい。C++ でもよかったんだけれど Ruby で溶いてしまった。

毎回最大公約数を求めてるのでSystem TestでTLE食らった。仕方ないね...

(問題 C に執着せず、問題 D を C++ で再実装すればよかった。後悔。)

解答: https://github.com/sorah/sorah-codeforces/blob/master/155/d.rb

Published at 2012-02-25 02:59:13 +0900 | Permalink
2012-02-23

tmux に移行した

dev

脱 screen した。

tmux が便利らしいと聞いて OS X 10.7.0 とかの頃使ってみたんだけど OS X のバグで tmux を終了させるとカーネルパニックするという症状が出ていたのでしばらく断念していたのだが、 久々に弄ってみたらカーネルパニックしなかったので移行してみた。

所要時間はだいたい2時間15分くらいだったな。

といっても実はその 10.7.0 の頃にある程度書いた .tmux.conf があるので、それを書く時間を含めたら2h30mくらいか。

やった事はこれくらい

  • .tmux.conf の修正
  • tmux 向けの cdd の導入
  • 上記の cdd に対応するため .zshrc に書いてあるいくつかの ruby スクリプトを修正、というかつけたけど案外不便な部分を切った。
  • いままでやろうとおもってやってなかったSSHの時のホットキーを変えるという事を実現した

tmux.conf はここにあります。loadavg.sh は同じレポジトリの bin/loadavg.sh にあります。

~/.tmux.prefix については .zshrc で生成してます。

まあ、tmux に移行した所で今までとそんなに変わらないと思うけどね。

Published at 2012-02-23 11:31:10 +0900 | Permalink
2012-02-20

Xcode 4.3 を入れました。

dev

Xcode 4.3 を入れました。

Xcode 4.3 または CLI tools を入れた話 , デブサミ2012 の写真 - HsbtDiary(2012-02-18) 等で言及されていたのは行かの点:

  • /Developer がなくなって、/Applications/Xcode.app/Contents/Developer になるらしい
  • /usr/bin/gcc などは別パッケージになる
  • autoconf さようなら

とりあえず自分は Mac App Store で入れるのが嫌いなので dmg を developer.apple.com から引っ張ってこようと思ったら "View in Mac App Store" とか書いてあるの。

その下にある Additional Downloads から "Xcode 4.3 for Lion (xcode_4.3_for_lion.dmg)" と "Command Line Tools for Xcode (command_line_tools_for_xcode_.dmg)" をダウンロードしてきた。

Xcode 4.2 まではパッケージだったが今回から dmg には Xcode.app 一つが入っていた。Applications にコピーして終わる。 起動した後は Xcode に iOS Devices 関係のパッケージを入れろと言われたけれど。

あと、 HDD 容量 7GB ほど節約できるという内容の記事 (XcodeからCommand Line Tools for Xcodeに切り替えたらHDD使用容量が7GB減った - Glide Note - グライドノート) があったので自分でも調べた。

Filesystem      Size   Used  Avail
/dev/disk1      120G   108G   9.1G # Xcode 4.2 削除前
/dev/disk1      120G   108G    12G # Xcode 4.2 削除後
/dev/disk1      120G   112G   8.4G # Xcode.app コピー直後
/dev/disk1      120G   112G   8.4G # Xcode.app 起動後、iOS Devices の接続周りのパッケージをインストールした後
/dev/disk1      120G   112G   7.8G # CLI ツールインストール後

9.1 - 7.8 = 1.3 (GB) と Xcode 4.3 にアップデートしたら使用容量が増えました \(o)/ (iOS の開発とかするから仕方ない。我慢しよう。)

測定と Xcode 4.2 の削除は以下:

  • 容量の測定は df -H
  • Xcode 4.2 の削除は sudo /Developer/Library/uninstall-devtools --mode=all

あと、残念ながら autoconf は無かった。

homebrew-alt から引っ張ってくる。

$ brew install https://raw.github.com/adamv/homebrew-alt/master/duplicates/autoconf.rb
######################################################################## 100.0%
==> Downloading http://ftpmirror.gnu.org/autoconf/autoconf-2.68.tar.gz
######################################################################## 100.0%
==> ./configure --prefix=/Users/sorah/brew/Cellar/autoconf/2.68
==> make install
==> Caveats
This formula is keg-only, so it was not symlinked into /Users/sorah/brew.

The OSX shipped autoconf is more than 5 years old, and missing many
critical bug-fixes compared with the latest upstream.
In order to prevent conflicts with the system autoconf, this formula
is keg-only.

Generally there are no consequences of this for you.
If you build your own software and it requires this formula, you'll need
to add its lib & include paths to your build variables:

    LDFLAGS  -L/Users/sorah/brew/Cellar/autoconf/2.68/lib
    CPPFLAGS -I/Users/sorah/brew/Cellar/autoconf/2.68/include
==> Summary
/Users/sorah/brew/Cellar/autoconf/2.68: 66 files, 2.6M, built in 16 seconds
$ brew link autoconf

そして一応 xcode-switch しておく

$ sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer

これで終わり。

Published at 2012-02-20 17:24:51 +0900 | Permalink
2012-02-10

Banshee に iTunes ライブラリをインポートする時に日本語なファイル名の一部で not found 言われる件

dev

前提

  • netatalk の AFP サーバーに対してファイルを転送した。

現象

Banshee という Linux の iTunes みたいな音楽管理ソフトの iTunes ライブラリ取り込み機能を利用した時に日本語ファイル名の一部で存在するのに存在しないと言われる。

原因

OS X の HFS+ は Unicode の Normalization Form D という方向で符号化された物がファイル名として使われている。

Normalization Form とは何か

Normalization Form とは Unicode は複数の形で一つの文字を表す事ができるので、それをどちらかに一般化 (normalize) する時に使う変換方法等の事。

http://unicode.org/reports/tr15/#Norm_Forms の Table 1. を見ると Normalization Form は 4 種類あって、

  • Normalization Form D (NFD) - Canonical Decomposition, 正準等価 で文字を 分解
  • Normalization Form C (NFC) - Canonical Composition, NFD で文字が一度正準等価で分解された後に正準等価で 結合 される
  • Normalization Form KD (NFKD) - Compatibility Decomposition, 互換等価 で文字を 分解
  • Normalization Form KC (NFKC) - Compatibility Composition, NFKD で文字を一度互換等価で分解した後に互換等価で文字を 結合

文字の分解・結合とは、上記したとおり Unicode はひとつの文字でも複数のバイト列で表面上同じ文字を表すことができる。

  • 分解 はなるべく一つの文字を複数に分ける事
  • 結合 はなるべく複数の文字からなる一つの文字をひとつにする事

たとえば「 」については「 」 + 「 」という風に分ける事ができる。この分ける事が分解で、これを「 」に戻す事が結合。もちろん「 」は実際 Finder 等では一つの文字に結合されて見える。一部のソフトウェア等を使った時にばらけて視えるかもしれないけど。Wine のファイル選択ダイアログとかね。

OS X の HFS+ はこの Normalization Form D を一部もじった物が使われているそうで。 要するになるべく文字が分けられているという。これを UTF-8-MAC と呼ぶらしい。

で、それが何?

Linux に転送するときに netatalk の AFP サーバーを使った。 この時 netatalk はこの UTF-8-MAC なファイル名を NFC で結合してくれているらしい。

しかし iTunes Music Library.xml, ファイル名等を記録しているライブラリファイルに入っているファイル名はまだ UTF-8-MAC のままである。

つまり、ファイルシステムには NFC されたファイル名なのに iTunes ライブラリに記録されているのは UTF-8-MAC なファイル名のままだから Not Found 言われる。

直す

なんというか、最初 Perl の Encode::UTF8Mac とかがラクなのか面倒だなと思ったら Ruby 1.9 の Encoding にあった。ありがとう成瀬さん!

というわけで Ruby 1.9 系では何も考えずに UTF-8-MAC の変換ができるよ! やったね!

URI エスケープ解く時に CGI じゃなくて URI 使ってるのはスラッシュとかまでエスケープしてほしくないから。これでも &#… みたいな記号表記があった時に #%23 にしてエラーがでてしまわないように &%23&# に戻してやる必要があった。

スクリプト

例によって 1.9 系が必要です。1.9.3 未満で動くかしらないけど。

https://gist.github.com/1781204

自己責任でね!

使い方

itunes_nfc.rb にスクリプトを保存したとすると:

$ cp iTunes\ Music\ Library.xml iTunes\ Music\ Library.orig.xml
$ ruby itunes_nfc.rb iTunes\ Music\ Library.xml > iTunes\ Music\ Library.xml

これで OK.

おまけ

Banshee さん iTunes Music Library.xml が異常だとインポート時にフリーズする…

参考文献

Published at 2012-02-10 12:07:51 +0900 | Permalink
2012-01-28

Matcher

dev

Matcher という物を作った。パブリックドメインとするので自由に使ってください。

ruby/matcher/matcher.rb at master from sorah/sandbox - GitHub

使い方

Matcher.new(obj, default = DEFAULT_KEY) obj にハッシュを渡して、その後 Matcher#match?(*conds) にマッチ条件を渡すと truefalse が返ってくる。

また、Matcher#match(*conds) でマッチした部分の配列等が返ってくる。

渡すハッシュでマッチ対象にできるのは {a: "b", b: "c"} といった1階層のHashだけで、複数の階層にわたるハッシュに対しては微妙。今回これを作った時にそれは想定してないのでどうでもいい。 誰かやってくれ。

引数 default

デフォルトだと Matcher::DEFAULT_KEY.

default は後述するマッチ条件でマッチ対象のキーが指定されてない時に参照するキーとなってる。

conds に使えるオブジェクト等

そもそも*conds引数は可変数引数になっている。

まず複数の引数を渡すと、渡した条件のうちいずれか一つにマッチすればマッチした扱いになり、全部にマッチしなければマッチしない扱いになる。

条件には、Regexp のオブジェクトを渡すとその正規表現にRegexp#matchでマッチするかどうかを確認、それ以外は==メソッドで確認される。

m = Matcher.new({foo: "bar", bar: "foo"}, :foo)
p m.match?("bar") #=> true
p m.match?("foo", "bar") #=> true
p m.match?(/fo/) #=> true
p m.match?("bar") #=> false
p m.match?(/b/) #=> false

普通にArrayを渡すと、これも複数の引数を渡した時のように配列内のオブジェクトを条件とみなしどれかにマッチしたときにマッチした扱いにする。が、あまり意味はないよね。ここでは。

Hash も渡す事ができる。Hash を渡すと、:any, :all を除いたキー以外だと、デフォルトのキーではなくそのキーに対してマッチするかどうかになる。で、何も指定 (後述する:anyとか:allとか) しない限りは、そのHashのどれかのキー(もちろんany,all以外)がマッチすればマッチした事になる。

p m.match?(bar: "foo") #=> true
p m.match?(bar: /f/) #=> true
p m.match?(bar: /bar/, foo: "bar") #=> true

ただ :any:all キーを除いては、そのキーにHashを入れてさらに条件を指定しようとしても意味がない。そのHashとの比較になります。Array:allとかを使っていない限りは「いずれかにマッチ」になる。

p m.match?(foo: ["foo", "bar"]) #=> true

そして :any キー は、その名の通り :any キーの値に入れた条件どれかにマッチすればマッチしたことになる。

:all キーもその名前の通り :all キーの値に入れた条件すべてにマッチすればマッチしたことになる

両方の値にはさっき書いた条件をそのまま評価するので何を入れても良い。ただ、その条件の「いずれかにマッチ」等が :all だと「全てにマッチ」に変わるだけ。

:any キーは :all の中で一部を「このいずれか」にしたい時に便利。

普通の条件式等でいうと {all: {a: {any: [1,2,3]}, b: /c/}[1,2,3].include?(a) && /c/.match(b) みたいな感じ。

p m.match?(all: {foo: "bar", bar: "foo"}) #=> true
p m.match?(all: {foo: "foo", bar: "foo"}) #=> false
p m.match?(all: {foo: [/^f/,/o$/], bar: "foo"}) #=> true
p m.match?(all: {foo: [/^o/,/o$/], bar: "foo"}) #=> false

:raw キーのみを含んだハッシュをマッチ条件として渡したりすると、そのArrayと==trueになるか等になる。 要するに条件のカスタマイズではなくそれと比較させたいとかいう場合。

また match? ではなく match を使うと正規表現のMatchData等がとれ、条件にマッチしないときはfalse。

p m.match(foo: /b/, bar: /ba/) #=> [{:foo=>#<MatchData "b">}]
p m.match(foo: ["foo", /b/])   #=> [{:foo=>#<MatchData "b">}]
p m.match(/fo/, /ba/)          #=> [#<MatchData "ba">]
p m.match(/fo/)                #=> false
p m.match("foo", "bar")        #=> ["bar"]

その他

その他使い方・返り値が帰ってくるのかは matcher_spec.rb を読んでください………

あとがき

しかし日本語でうまく書けないな。おれはもうだめだ。

Published at 2012-01-28 14:15:06 +0900 | Permalink
2012-01-24

limit of inotify

dev

Problem

When dropbox or guard says like:

  • Unable to monitor filesystem Please run: echo 100000 | sudo tee /proc/sys/fs/inotify/max_user_watches and restart Dropbox to correct the problem.
  • No space left on device - Failed to watch "…": The user limit on the total number of inotify watches was reached or the kernel failed to allocate a needed resource. (Errno::ENOSPC)

Solution

man inotify(7) says:

The following interfaces can be used to limit the amount of kernel memory consumed by inotify:

/proc/sys/fs/inotify/max_queued_events

The value in this file is used when an application calls inotify_init(2) to set an upper limit on the number of events that can be queued to the corresponding inotify instance. Events in excess of this limit are dropped, but an IN_Q_OVERFLOW event is always generated.

/proc/sys/fs/inotify/max_user_instances

This specifies an upper limit on the number of inotify instances that can be created per real user ID.

/proc/sys/fs/inotify/max_user_watches

This specifies an upper limit on the number of watches that can be created per real user ID.

In this case, Dropbox and guard have to use many watches, so do this and increase max_user_watches.

# Check current maximum
$ cat /proc/sys/fs/inotify/max_user_watches
8192
# Increase the maximum
$ echo 100000|sudo tee /proc/sys/fs/inotify/max_user_watches
Password:
100000
# Check
$ cat /proc/sys/fs/inotify/max_user_watches
100000

Doing the above increases max_user_watches temporally.

To increase max_user_watches at boot, edit /etc/sysctl.conf and add fs.inotify.max_user_watches=100000 or fix fs.inotify.max_user_watches= to 100000.

(Note: I'm using gentoo so some other distros may have another way to do this…)

Published at 2012-01-24 14:24:52 +0900 | Permalink
2012-01-11

新マシン環境構築 (3) Gentoo を入れる

dev

新マシンの Windows をある程度設定した ということで Gentoo を入れます.

ただ,窓から Windows 投げ捨てたりはしませんが.

... Continue Reading...
Published at 2012-01-11 13:27:51 +0900 | Permalink
2012-01-11

新マシン環境構築 (2) Windows 設定

dev

新マシンの Windows を再インストール の続きです.

再インストールした Windows にソフトウェアを突っ込んで設定していきます.

... Continue Reading...
Published at 2012-01-11 13:24:46 +0900 | Permalink
2012-01-11

新マシン環境構築 (1) - Windows の再インストール

dev

"マシンが到着していました" の続きです.

開封して仮設置したので Windows を再インストールしてパーティションを切り直します.

... Continue Reading...
Published at 2012-01-11 13:20:31 +0900 | Permalink
2012-01-11

マシンが到着していました

dev

P1053055

だいぶ遅れてのエントリーとなりました.

9時くらいにヤマトがきた.午前中指定すばらしい...

マシンは Prime Galleria SH スペックはこんなもん

  • Windows 7 Professional
  • RAM 16GB (DDR3 SDRAM, PC3-10600, 4GB*4/ Dual Channel)
  • 2TB HDD
  • ブルーレイ(笑)

ということで開封の儀.

... Continue Reading...
Published at 2012-01-11 13:18:40 +0900 | Permalink
2011-12-05

Kernel VM

dev

(本記事は カーネル/VM Advent Calendar 2011 に参加している記事です.この記事は 5 日目の記事で,前日は @naota344 でした.)

カーネル/VM 探検隊には参加したことがない sora_h です.こんにちは!

さて,カーネル/VM advent calendar はテーマなんでもいいということですが,やはり前日を見るとカーネル関連じゃないと行けない気がしなくも無いですね……………!!!!

カーネルとVMといえばまあRuby の KernelRubyVMが思い浮かぶわけです.

ネタがないのでこの二つを解説しましょう.ごめんなさい!!!!

Kernel

Kernel とはすべてのクラスから参照できるメソッドが定義されているモジュールであり, Object はこいつを include している.

有名な例では puts とかopen() とかそういうのが Kernel にあります.

しかしこれを解説するのはあまり面白みが無いので RubyVM を解説しようと思います.

RubyVM

今回はそれのサブクラスである RubyVM::InstructionSequence を取り上げます.

これは Ruby 1.9 系列から搭載された VM, YARV (Yet Another Ruby Vm) の insq (instruction sequence, バイトコード(?)) に Ruby レベルからコンパイルしたりなどができるようになって います.

RubyVM::InstructionSequence.compile("puts 'a'")

等することでコンパイルする事が可能です.

コンパイルの結果は,それでかえってきた InstructionSequence のオブジェクトに対して disasm したものを puts などすると良いのではないでしょうか.

require 'pp'
puts RubyVM::InstructionSequence.compile("puts 'a'").disasm

またこの結果は ruby --dump=insns -e 'script' とか ruby --dump=insns foo.rb とかでも 確認することができます.

そして

RubyVM::InstructionSequence.compile("puts 'a'").eval

で実行することも出来ます.

で,これで生成されるバイトコードを見たからなんだ,という話なんですが, たとえば命令をいじってみたりとかして遊ぶことができますね.

YARV の命令群の実態は insns.def ファイルにあって,コンパイル時にそれを一つの C ファイルに変換しています.

なので,insns.def ファイルを編集してビルドすることで命令の動作が変わったりします.楽しいですね.

YARV の instructions を調べたりするには yhara さんが作った YARV Instructions, また YARV 自体の解説にはまだ執筆途中で中途半端なものの開発者である ささださん が書いている YARV Maniacs を読むと良いかもしれません.

参考資料

まとめ

ちゃんとネタは作っておこう

Published at 2011-12-05 14:59:07 +0900 | Permalink
2011-11-30

Coffeescripting with Ruby #advent11rb

dev

(本記事は Ruby Advent Calendar jp: 2011 に賛同している記事です.この記事は本 Advent Calendar 最初の記事になります.)

Ruby Advent Calendar の最初の記事です.どうもこんにちは.

さて,今回は Ruby と Coffeescript, javascript について語ります.

Ruby から Javascript を使う

さて最近はたくさん javascript のインタプリタがありますね.node とかだとコマンドラインインターフェースも充実しているし.

それらをつかえばもちろん ruby から js を使うことはできるわけです.しかし方法が多すぎる.

それをまとめるために execjs という gem があります.

これは複数の javascript 実行方法に対応していて,自動でどれが現在の環境において実行可能かを判別し どれか適当な方法で実行してくれます.

execjs/README.md 曰く,

つまり,execjs で Javascript を実行すれば適当な方法が採用されるので Ruby から Javascript を使うには向いています.

require "execjs"
ExecJS.eval "(function(name){ return ['hello', name, 'world'].join(' ') })('javascript')" #=> 'hello javascript world'

しかし, javascript を ruby から使うメリットはあるのでしょうか.

Coffeescript

Coffeescript という Javascript にコンパイルされる Javascript で実装された言語があります.

この言語は ruby に python をちょっと混ぜたものをコーヒーに突っ込んだような言語です.

Ruby 等を書いていて Javascript の書きにくさを実感しますが,Coffeescript を使うことでそれをある程度解消することができます.

最近だと Rails 3.1 などでデフォルトが Coffeescript になった事で Ruby 界で一層有名になった感じですかね.

Ruby から Coffeescript をコンパイルする

Rails 3.1 などもやっているように,Coffeescript を Javascript にコンパイルしています.

Coffeescript のインタプリタ (Javascript コンパイラ) は Javascript で実装されているため,JS が実行できれば Coffeescript のコンパイルをすることができます.

そして,先ほど紹介した execjs を利用して coffeescript を javascript にコンパイルする gem があります.

https://github.com/josh/ruby-coffee-script

これを使うことで簡単に coffeescript を javascript にコンパイルすることが可能です.

Sinatra では coffee :the_script などでこれを利用して coffeescript を javascript として render することが可能です.

では,Happy coffeescript life を!

Published at 2011-11-30 15:00:35 +0900 | Permalink