JavaScript ではよくある、こういう書き方。
一応説明すると、これは実行時に外側の無名関数を実行します。外側の無名関数は返り値として、内側の無名関数を返し、変数 counter には内側の無名関数が代入されます。
これの何が嬉しいのか。
- counter 関数が内部に持っている変数 i は隠蔽されており、外から変更できない。
- グローバル空間の汚染は counter 1 つだけ。
といったところでしょうか。とにかく、 JavaScript 脳の人はこういう感じのコードをよく書いている気がします。 JavaScript にはオブジェクト指向によくある protected や private といったアクセスレベルを制御する機能が無いため、これの応用で内部の変数やメソッドを隠蔽することが多いです。 Prototype や jQuery でもそういった使い方がされています。
このように、 JavaScript では無名関数の中にスコープを閉じ込めることができ、これをクロージャと呼びます。
で、最近久しぶりに勉強している Perl 。 Plack のコードを読んでいる中で、 Perl にも無名関数とクロージャがあるということを知ったので、試してみました。
上部のおまじない的なものを除けば、やってることは本質的に何も変わりません。
ついでに Ruby も。これもやっていることは特に変わらないと思います。
Python にも無名関数 (ラムダ) はあるので、同じようなことができそうな気がしたのですが、うまくいかず、代わりにこんな書き方に。
これはクロージャではなく、ジェネレータという機能を使っています。内部の変数が隠蔽されており、名前空間の汚染も 1 つだけですが、最初は関数だった counter にジェネレータをぶち込むというのは、お行儀的にはよくないかもしれません。
で、 PHP でも 5.3 からは無名関数・クロージャが使えるようになったので、試してみたのですが、以下の JavaScript 的な記述では parse error となりました …
以下のように書き換えると動きますが、これでは名前空間の汚染が 2 つです。
そして、何かもう方向を見失っている例。
変数の名前空間汚染は 1 つだけど、クラス名の名前空間まで汚染してしまっている上、返り値が文字列になっています。 (__toString はそのように定義しないといけないため)
そして、一応数値を返すようにしたものが以下。
なんか、 JavaScript と Perl の話だったはずが、暗に PHP を Dis る結果になってしまったので、今日はこの辺で。
Closure, JavaScript, Lambda, Perl, PHP, Python, Ruby
Google App Engine (以下 GAE) 上で Amazon の Product Advertising API を扱うべく、Python の XML ライブラリについて調べていました。どうも Pythonista の間では lxml というのがメジャーらしいので、さっそく組み込んでみたのですが、どうも動かない。
調べて見たところ、GAE 上では、セキュリティの関係上、C 拡張による Python ライブラリは動かないとのことで、lxml は使えないようです。
代替ライブラリを探す
C 拡張がダメということは、つまり Pure Python なライブラリなら OK、という解釈でいいのでしょうか。探してみたところ、ちょうど先日購入した Python クックブック 第2版 の p.479 に「XML 文書を Python のオブジェクトツリーに変換」というレシピが載っていました。
写経、そして修正
さっそく写経してみたのですが、動かない。しばらく調べた結果、誤植によるものと思われるバグを発見。その他いくつかの修正を加えたものを GitHub に公開しました。
主な変更点は以下の通りです。
- Xml2Obj.EndElement が上手く動かないのを修正
- UTF-8 に対応
- ファイルからではなく、文字列を XML として読み込むよう変更
- __getattr__ メソッドにより、Element.getElements() のショートカットを作成 (詳細は後述)
ただし、あくまでも習作であり、エラー処理等もかなり甘いので、実用的とは言えません。
その代わり、ちょっと遊ぶ程度にはちょうどいい手軽さかも。
コード
テストコード
__getattr__ による Element.getElements() へのショートカットについて
__getattr__ というのは、インスタンスに存在しないプロパティを呼び出そうとしたときに呼び出されるもので、PHP でいうと、マジックメソッドの __get にあたるものと言えるでしょう。
これにより、以下のようなショートカットを実現しています。意味はどちらも同じです。
終わりに
もともと GAE に組み込むことを目的として上記ライブラリを修正したわけですが、実はまだ組み込めてません・・・。ただ、expat を GAE に組み込んでいる例はネット上に転がっているので、まぁこれもいけるのではないかと。真相はまた今度。
関連リンク
GAE, Google App Engine, Python, XML
PHP-users のメーリングリストへの告知がきっかけで行って参りました。予想をはるかに越える、素晴らしいイベントだったので、その凄さを簡潔に紹介。
主催者が凄い
主催者である桑田氏は過去に、RubyKaigi、PHP Conference、YAPC など様々なイベントにおいて講演を行っている。Web サイト kuwata-lab homepage においては、Python 向けのテンプレートエンジン pyTenjin を始め、多数の開発者向けプログラムを提供している。根っからのプログラマーという印象。
間口の広さが凄い
タイトルの通り、PHP ユーザーを対象とした講習会であり、プログラミングはある程度できることが求められるものの、「Python に関しては全く知らない」という人でも参加できるようにプログラムされている。それでいて、最後には Google App Engine 上で、Big Table を利用したプログラムを動作させるところまで行く。
反面、ある程度 Python が書ける人に取っては、退屈な部分もあったかもしれない。講習会前に 3 日ほど予習していただけの私でさえ、最初の数時間は既に覚えた文法のおさらいがほとんどという感じ。
ただ、桑田氏の、プログラミング一般や、Python 言語仕様に関する理解は凄まじいものがあり、「オブジェクト指向の仕組み」や、「メソッドの名前解決の優先順位」などの、興味深い話も聴けるので、Python がある程度書ける人にも、十分楽しめる内容だったことでしょう。
スケジュールが凄い
10:00 ~ 21:00 という予定で、実際にはそれも少しオーバー。それだけの長時間を、桑田氏ひとりで進める。もちろん休憩はあるものの、全員心地よい疲労感とともに講習会を終えたことと思います。
テキストが凄い
講習会は、桑田氏自作のテキストをベースに進められる。その量、PowerPoint で 200 ページ超。Python と PHP を比較しながらの解説も大変わかりやすい。
コストパフォーマンスが凄い
上記のテキストを始め、準備にはかなりの時間が割かれていることと思われますが、それでも参加費は 1 人 500 円と格安。元が取れないわけがない。
また、女性、カップル、中学生以下は無料となるそうです。
まとめ
初心者にもやさしく、全員が一定の目標を達成に到達でき、主催者がともに喜んでくれる、楽しい講習会でした。そんなわけで、次回も是非参加したいと思っています。
(ですが、次回はもうちょい早めに終わって、懇親会とかもあればと思っていたり。)
仕事で Python を使う、という人は、日本にはなかなかいないかと思いますが、純粋にプログラミングが好きな人は、是非次の機会に参加してみてください。
関連リンク
その他の参加者によるブログ
PHP, Python