create_functionはクロージャにはなれない

Rubyだとこんな感じで書ける

def counter
  i = 0
  lambda{|n| i += n}
end

count = counter
puts count.call(1) #=> 1
puts count.call(2) #=> 3
puts count.call(3) #=> 6


PHPの場合も同じ結果を期待したけど、クロージャとしては動いてくれないらしい。

<?php
function counter() {
	$i = 0;
	return create_function('$n',"$i = $i + $n;"); 
}

$func = counter();
echo $func(1); // Parse error: syntax error, unexpected '='
echo $func(3);
echo $func(5);


文字列をダブルクォーテーションで囲っているため、$iは文字列内で変数として評価されてしまう。
そのため、create_function内では以下のような式が入ることになる。

0 = 0 + 1

そりゃ動かないわな。

ちなみにシングルクォーテーションにすると、function内のローカル変数扱いになるため、外の変数は参照されません。

5.3のλ導入までは使えないってことですかね。

Sinatra勉強会@万葉に行って来ました

Sinatraという軽量フレームワークについての勉強会に参加してきました。

Sinatraの印象

フレームワーク全体の印象としては、簡単にURLディスパッチャーを利用するためのものという印象。
haml&sassやerbなどのテンプレートエンジンや、sequal, DataMapperといったDBアクセスライブラリを組み合わせることで、簡単にアプリケーションが作成できる。

本編

詳しくはid:tsuyoshikawa 氏のエントリをご覧ください。

懇親会

  • 東京 × Emacs で何かが起こるらしい
  • Vim vs Emacs
  • PHPは恐ろしい
  • なんだかすごい人だらけで、若干気後れしていたのは内緒

その他

haml 楽しい!

勉強会参加前にサンプルを組んでみた時に、初めてhamlを使ってみました。あの糞面倒くさいhtmlがこんなに簡単に書けるなんて!!と感動しきり。
余計な記号がないのが素晴らしすぎる!!

WanderlustでGmailを読めるようにする

最近Emacsいじってばかり。
Emacsでメールも扱えるようにしておく。
メールは全てGmailに集中させているので、Gmailに接続できればよい。

apel, FLIM, SEMIのインストール

前提となるものを入れる。APELは先日入れたので割愛。

FLIM

http://www.kanji.zinbun.kyoto-u.ac.jp/~tomo/elisp/FLIM/

$ make install LISPDIR=~/lisp
SEMI

http://www.kanji.zinbun.kyoto-u.ac.jp/~tomo/elisp/SEMI/

$ make install LISPDIR=~/lisp

Wanderlustのインストール

公式ページftpになぜか全て繋がらないので、CVSか他からダウンロードする。
今回は下記から持って来た
http://www.jpl.org/elips/wl/wl-2.14.0.tar.gz

$ make install LISPDIR=~/lisp PIXMAPDIR=~/lisp/wl/icon

あとは設定ファイル。
各ツールを .emacs でロードして、細かい設定は .wl に書く。
あと、.folders というのも必要らしい。

~/.emacs

;; flim
(add-to-list 'load-path "~/lisp/flim")

;; semi
(add-to-list 'load-path "~/lisp/semi")
(require 'mime-setup)


;; wanderlust wl.el
(add-to-list 'load-path "~/lisp/wl")
(require 'wl)
(require 'wl-draft)
(autoload 'wl-other-frame "wl" "Wanderlust on new frame." t)

~/folders

%inbox "inbox"
+trash "Trash"
+draft "Draft"

~/.wl

;; wanderlust setting

;; icon directory
(setq wl-icon-directory "~/lisp/wl/icon")

;;; mail
(require 'ssl)
(setq ssl-program-name "openssl")
(setq ssl-program-arguments '("s_client" "-quiet" "-host" host "-port" service))

;; IMAP
(setq elmo-imap4-default-server "imap.gmail.com")
(setq elmo-imap4-default-user "<username>@gmail.com") 
(setq elmo-imap4-default-authenticate-type 'clear) 
(setq elmo-imap4-default-port '993)
(setq elmo-imap4-default-stream-type 'ssl)

(setq elmo-imap4-use-modified-utf7 t) 

;; SMTP
(setq wl-smtp-connection-type 'starttls)
(setq wl-smtp-posting-port 587)
(setq wl-smtp-authenticate-type "plain")
(setq wl-smtp-posting-user "mattofransen")
(setq wl-smtp-posting-server "smtp.gmail.com")
(setq wl-local-domain "gmail.com")

(setq wl-default-folder "%inbox")
(setq wl-default-spec "%")
(setq wl-draft-folder "%[Gmail]/Drafts") ; Gmail IMAP
(setq wl-trash-folder "%[Gmail]/Trash")

(setq wl-folder-check-async t) 

(setq elmo-imap4-use-modified-utf7 t)

(autoload 'wl-user-agent-compose "wl-draft" nil t)
(if (boundp 'mail-user-agent)
    (setq mail-user-agent 'wl-user-agent))
(if (fboundp 'define-mail-user-agent)
    (define-mail-user-agent
      'wl-user-agent
      'wl-user-agent-compose
      'wl-draft-send
      'wl-draft-kill
      'mail-send-hook))

完了

お疲れ様でした。
メールの読み書きができるようになったのはいいが、Archiveのやり方などが全くわからんので戸惑っている。

diredの罠

emacsでdiredを立ち上げて、

!mv DIRNAME 

とかやったら、rm -rf された。
消えたのはコードスニペットフォルダ。


幸いGithubにある程度残ってたので、そこから70%程度復旧。
'!' なんてもう使いません。

2009/06/07 23:50 追記

diredで上記のコマンドを実行した時に、カーソルが合っていたディレクトリ (TARGETDIR) へ mv されていた。
つまり、上記のコマンドは

! mv DIRNAME TARGETDIR

という動作になっていた。

無知は罪です。dired様ごめんなさい。

elscreenを使う

emacs 上でGNU screenみたいな動作ができるらしい。Meadowのパッケージに含まれていた。
Macでも使いたいので入れてみる。

apelが必要なのでそれも入れる。

apel

http://cvs.m17n.org/elisp/APEL/index.html.ja.iso-2022-jp

$ make
$ make install LISPDIR=~/lisp VERSION_SPECFIC_LISPDIR=~/lisp/emu

(2009/06/20 インストールディレクトリを修正)

elscreen

Fragments of Reality - ElScreen

tarボールを落としてきて開封。
とりあえずはelscreen-gfだけ使う。

(add-to-list 'load-path "~/lisp/elscreen")
(require 'elscreen)
(require 'elscreen-gf)

なんていうかもう、とてもとても快適です。

magit.el を試してみた

egg.elいまいちーと書いたところ、

@gom egg.elが嫌ならmagit.elでどう?俺的にはそっちのが使いやすいけど。

http://twitter.com/rubikitch/statuses/1901340067

id:rubikitch さんに教えてもらいました。ありがとうございます。
というわけで、早速試してみた。

インストール

makeするのね

$ git clone git://github.com/jdhuntington/magit.git
$ ./autogen.sh
$ ./configure --prefix=$HOME/lisp/magit
$ make
$ sudo make install

.emacsの書き換え

(add-to-list 'load-path "~/lisp/magit/share/emacs/site-lisp/")
(require 'magit)

git status

statusバッファ上でキー操作を行う。
キー操作は以下の通りで、大体の操作はできる模様。

違うbranchにpushするとか、refspecをごちゃごちゃいじる辺りはどうなってるのか不明。

Magit User Manual

M-x magit-status
  • TAB: セクションの表示を切り替える
  • M-1, M-2, M-3, M-4: セクション表示の切り替え
  • Section: Untracked file
    • s: ファイルをステージに追加する(git add)
    • i: .gitignoreにファイルを追加する
    • C-u i: ignoreファイルを指定する
    • I: .git/info/excludeにファイルを追加する
    • k: ファイルを削除する*1
  • Section: Unstaged Changing / Staged Changing
    • s: ファイルをステージに追加する(git add)
    • S: 全ファイルをステージに追加する
    • u: ファイルをステージから降ろす
    • U: 全ファイルをステージから降ろす
    • k: 変更を取り消す
    • c: コミットログを書く
    • C: コミットログをチェンジログ形式で書く?
    • C-c C-c: コミットする(git commit)
    • C-c C-a: コミットをやり直す(git commit --amend)
  • Log
    • l: ログ一覧を表示する(git log)
    • L: 詳細ログの一覧を表示する(git log --stat)
    • ログを選択して RET: ログの詳細を表示する(git log -p)
    • a: コミットを今のブランチに適用する(git cherry-pick & NOT commit)
    • A: コミットを今のブランチに適用し、コミットする(git cheery-pick & git commit)
    • v: コミットを取り消す(git revert)
    • C-w: コミットのsha1ハッシュをコピーする
    • =: 今のコミットとの差分を表示する
    • .: コミットをマークする
  • h or H: 今のHEADまでのログを表示する
  • d: ワーキングコピーからあるコミットまでの差分を表示する(git diff)
  • D: 2つのコミットの差分を表示する
  • t or T: タグを作成する(git tag)
  • x: コミットを取り消す(git reset --soft)
  • X: コミットと変更を取り消す(git reset --hard)
  • Stash
    • z: stashを作成する(git stash)
    • a: stashを適用する(git stash apply)
    • A: stashをpopする(git stash pop)
    • k: stashをdropする(git stash drop)
  • b: ブランチを切り替える(git checkout)
  • B: 新規ブランチを作成して切り替える(git checkout -b)
  • w: wazzup?
  • m or M: マージを行う
    • X: 手動マージを中止する
    • e: resolved conflict?
  • R: rebase
  • P: push (default remote, current branch)
  • f: git remote update
  • F: pull
  • git svn
    • N c: git svn commit
    • N r: git svn rebase

後半は疲れてしまったのでかなり適当です。
必要なコマンドは押さえられていて、いい感じに扱えそう。

*1:物理的に削除されるようだ

久々にEmacsをいじくってみる

Textmateも便利でいいのだけど、補完機能とか考えるとやっぱりEmacsだなーと思い始めた今日この頃。


とりあえず anything と rcodetools に慣れると幸せになれそう。