coffeescript触ってみた
文法ぱっと見ファーストインプレッション
https://sites.google.com/site/sappariwiki/coffeescript/coffeescript-langref
ここを読んでみて、coffeescriptの文法はぱっと見た感じかなり好みだなと思った。かなり良いとこどりの言語。ちなみにぼくはjavascriptもあんまりたくさん書いたことはありません。
関数
関数定義はHaskellに似ているけど、若干違和感がある。Haskellと=の位置が違うからかもしれない。
デフォルト引数は良いね。可変長引数は良いけど、おれの短いjs歴のなかではまだ使いたかったことがない。
内包表記
内包表記はmapでいいじゃんと思いつつも、あるとつい使っちゃう。何がそうさせるのかわからないけど、もしかしたらそれっぽく見えるからってだけかもしれない。ていうかjsってmapもなかったっけ?
すべては式(できるだけ)
これは良い。もう全部式でいいよ。文とかいらね。ifもforも値を返す。そうでなくっちゃね。
存在演算子
これも良いね。jsのめんどいところをかっこ良くカバーしてる感じがする。
その他
後置のifとかperl出身の僕にはうれしい。なければないでかまわないけど。比較連結式もあればうれしいレベル。なくてもかまわない。
ちょっと書いてみてセカンドインプレッション
ということで最近書いてたjsをcoffeescriptに置き換えてみた。それで思ったこと。
コールバックで渡す無名関数のところがちょっとわかりにくい
関数定義は
hoge = (x, y) -> fuga x baba y
みたいな感じなわけだけど、無名関数はどうかくんだろうと思って適当に書いてみたら、それであってたみたい。
(x, y) -> fuga x baba y
でだ、jsってコールバックでがんがん無名関数渡すじゃない?そのときにこの関数定義とインデントでブロックを表すってルールでこんな感じになると思うんだ。
insertRecord = (item_id, value) -> db.transaction (tx) -> tx.executeSql select_count_traininngs, [], (tx, res) -> dt = new Date() now = dt.toISOString() tx.executeSql insert_traininng, [res.rows.item(0).cnt + 1, 1, localStorage['user'], item_id, value, now], (tx, res) -> console.log(res); update(), (tx, error) -> reportError 'sql', error.message
元のjsはこう
function insertRecord(item_id, value) { db.transaction(function(tx) { tx.executeSql(select_count_traininngs, [], function(tx, res) { var lastId = res.rows.item(0).cnt; var dt = new Date(); var now = dt.toISOString(); tx.executeSql(insert_traininng, [lastId + 1, 1, user, item_id, value, now], function(tx, res) { console.log(res); update(); }, function(tx, error) { reportError('sql', error.message); }); }); }); }
見た目は近いけど、コールバックで無名関数を渡していることが僕にはわかりにくい。2個目以降の'->'のある部分が全部コールバックで無名関数を渡しているんだけど、たとえば db.transaction (tx) -> の部分とか(tx)以降がdb.transactionの引数だってぱっとわかる?慣れの問題かもしれないけど、ちょっと止まっちゃう。(S式みたいに外側に括弧があればわかりやすいのに!)
javascritpのコードが生成されるのでそれを見ながら直せる
なんかあってるか自信の無いところとかは生成されたjsのコードを見ながら確認したり修正したりできる。
TRY COFFEESCRIPTが便利
http://jashkenas.github.com/coffee-script/のTRY COFFEESCRIPTにペーストしながら書いた。emacsのcoffee-modeをいれたんだけどまだあまり使いこなせてない。きっとこいつでもリアルタイムのjs変換したりできるに違いない。
まとめ
今後もjsをしばらくやってくと思うので、coffeescriptを使ってってみようと思う。
tea-time.elでポモドーロ(ついでにgrowlで通知するようにした)
ポモドーロをやりたいが、あたらしい職場でまだキッチンタイマーの音を鳴らす勇気がないので、emacsのタイマーを探してみた。
そしたらtea-time.el*1というのがあって、見てみるとこれがちょうど良さそうなので使ってみる。
インストール
M-x auto-install-from-url https://raw.github.com/krick/tea-time/master/tea-time.el
して、.emacs等に
(require 'tea-time) (setq tea-time-sound "path-to-sound-file") (setq tea-time-sound-command "afplay %s")
を貼付ける。
以上。
使い方
M-x tea-time
すると「How long? (min)」って聞かれるので、セットしたい時間を入力する。
あとは時間が来るとミニバッファに通知してくれる。
growlで
でも、ミニバッファの通知は控えめすぎてこれじゃ気づけないかもしれない、、ということでgrowlで通知するようにしてみた。
growlやgrowlnotifyがもしインストールされていなければ、ここ*2からインストールしておく。
で、適当にgrowl通知用の関数をでっち上げる。一応priorityとstickyにも対応しておいた。
(defun my-growl-notification (title message &optional priority sticky) "" (shell-command (format (concat "growlnotify -t \"%s\" -m \"%s\"" (if priority (concat " -p " (number-to-string priority)) "") (if sticky " -s ")) title message)))
次に、ちょっと手抜きしてtea-time.elのtea-timer関数を書き換える。
(defun tea-timer (sec) "Ding and show notification when tea is ready. Store current timer in a global variable." (interactive) (run-at-time sec nil (lambda (seconds) (tea-time-play-sound) ;; (tea-time-show-notification (format "Time is up! %d minutes" (/ seconds 60))) (my-growl-notification "tea-time.el" (format "Time is up! %d minutes" (/ seconds 60))) ; 上の行をコメントアウトして、この行を追加した ) sec))
関数定義してghciでloadしてささっと試す
最近Haskell勉強中なんだけど、ghciで普通に関数定義できないみたい*1なんで、ちょっと不便してた。でもコンパイルするのはメンドイ。
そしたら今日ghciでその関数定義したファイル(というかモジュール?)をloadしてghci内で使えることを知った。
hoge.hsというファイル内に関数定義を書いて
import Chara lstrip :: String -> String lstrip = dropWhile isSpace
ghciで:loadするとすると、ghci内でその関数が使えるようになる。
*Main> :load hoge [1 of 1] Compiling Main ( hoge.hs, interpreted ) Ok, modules loaded: Main. *Main>
これでインタラクティブシェル的な感じで関数定義できて便利。
*Main> :t lstrip lstrip :: String -> String *Main> lstrip " jkjkj " Loading package filepath-1.1.0.4 ... linking ... done. Loading package old-locale-1.0.0.2 ... linking ... done. Loading package old-time-1.0.0.5 ... linking ... done. Loading package unix-2.4.0.2 ... linking ... done. Loading package directory-1.0.1.1 ... linking ... done. Loading package process-1.0.1.3 ... linking ... done. Loading package array-0.3.0.1 ... linking ... done. Loading package time-1.1.4 ... linking ... done. Loading package random-1.0.0.2 ... linking ... done. Loading package haskell98 ... linking ... done. "jkjkj " *Main> lstrip " \tmuu" "muu" *Main>
なんか初回実行時だけloadとかlinkとか入るのかな?良くわからないけど。
*1:let使えばできるっぽい
Pythonで辞書から存在しないキーで参照したときにもエラーにならないようにしたい
pythonで辞書からhoge['fuga']という書き方で存在しない無いキーで引くとKeyErrorになった。
無いときはNoneを入れたいなと思っていたので、どうしたら良いかと思っていたら@takezo70がgetというメソッドを教えてくれた。
辞書.get(キー, 無かったときの値)
kay-frameworkを触ってみるつもりが、python2.5用のsslモジュールをインストールするのに苦労した話
kayを試してみようと思ってDLしてきてチュートリアル*1にある通りにプロジェクト作成して、アプリ作成して、のところでつまずく。
[07-17 22:21:35 suzuki@suzuki-shinichirou-no-MacBook-Air /Users/suzuki/tmp/kaytest/myproject] python manage.py startapp myapp Running on Kay-1.1.1 /Users/suzuki/tmp/kaytest/myproject/kay/ext/media_compressor/media_compiler.py:14: DeprecationWarning: the md5 module is deprecated; use hashlib instead import md5 [07-17 22:22:16 suzuki@suzuki-shinichirou-no-MacBook-Air /Users/suzuki/tmp/kaytest/myproject]
おっと、hashlibが入ってない。もう入ってると思って手順飛ばしてた。
いや、py25-hashlibは入ってた。python2.5を指定して実行するとできた。しかしpy25-socket-sslがない。pilもない。これらを入れるか。どうやっていれれば良いのかな?良くわからないのでmacportsで入れる。
しかしエラーで入らない。どうやら僕のmacのpython2.5はmacportsで入れたものじゃないらしく(元々入っていた?)ゆえにmacportsでpy25-socket-sslなどが入れられないっぽい。かといって今更python2.5をmacportsで入れ直すのも面倒だし、、
(ちなみにssl以外のpilやipythonは
sudo easy_install-2.5 pil sudo easy_install-2.5 ipython
でインストールできた)
ぐぐってやり方が書いてあるページを見つけた*2けど、その先のインストーラがおいてあるっていうリンクが切れていたり、、
そんなことをグニャグニャやっていたのだけど、http://pypi.python.org/pypi/ssl#downloadsからDLしてsetup.py installでさくっとインストールできた。
[07-18 02:00:18 suzuki@suzuki-shinichirou-no-MacBook-Air /Users/suzuki/Downloads/ssl-1.15] sudo python2.5 setup.py install Password: looking for /usr/include/openssl/ssl.h looking for /usr/include/krb5.h running install running build running build_py running build_ext running install_lib running install_data copying test/test_ssl.py -> /System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/test copying test/keycert.pem -> /System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/test copying test/badcert.pem -> /System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/test copying test/badkey.pem -> /System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/test copying test/nullcert.pem -> /System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/test running install_egg_info Writing /Library/Python/2.5/site-packages/ssl-1.15-py2.5.egg-info [07-18 02:00:25 suzuki@suzuki-shinichirou-no-MacBook-Air /Users/suzuki/Downloads/ssl-1.15]
またいつかのためのメモ