Emacs22 で pycomplete

なんか Emacs22 だと pycomplete が動かなかったので Hack。
プロパティ付きの文字列の入出力周りに変化でもあったのかな。

--- pycomplete.el.orig  2005-12-02 10:30:11.000000000 -0500
+++ pycomplete.el       2006-09-01 20:13:55.718750000 -0400
@@ -26,7 +26,7 @@
              "^\\(import \\|from \\([A-Za-z_][A-Za-z_0-9]*\\) import \\).*"
              nil t)
        (setq imports (append imports
-                             (list (buffer-substring
+                             (list (buffer-substring-no-properties
                                     (match-beginning 0)
                                     (match-end 0))))))
       imports)))

Meadow で python-mode + pymacs + pycomplete を使う

Meadow で pycomplete を使うメモ。

Pymacs のインストール

http://pymacs.progiciels-bpi.ca/ から Pymacs-0.22.tar.gz をダウンロードしてきてインストールする。

% cd Pymacs-0.22
% python setup.py install

pymacs-services を起動するためのバッチファイル pymacs-services.bat を作って、 PATH の通ったところにおいておく。

% type C:\Python24\pymacs-services.bat
python C:\Python24\scripts\pymacs-services

pymacs.el は load-path の通ったところにコピーする。

python-mode のインストール

http://python-mode.sourceforge.net/ から python-mode-1.0.tar.gz をダウンロードして load-path の通ったところにコピーし、pycomplete.py は C:\Python24\Lib\site-packages\ あたりにコピーする。

Emacsの設定

こんな感じ。indent-tabs-mode の設定はお好みで。

(autoload 'python-mode "python-mode" nil t)
(add-to-list 'auto-mode-alist '("\\.py\\'" . python-mode))
(add-hook 'python-mode-hook
          '(lambda()
             (require 'pycomplete)
             (setq indent-tabs-mode nil)))

使い方

M-TAB 補完
C-c C-c バッファの内容を Python で実行
C-c | リージョンの内容を Python で実行
C-c ! Python Shell に移動

Emacs22 付属の python-mode

Emacs22 からは python.el が付いてきてて、pycomplete なしでも補完ができるのだけど、補完機能が中途半端なのが残念。使うなら結局 pycomplete と組み合わせることになるかな。まぁ、そもそも python-mode.el と何が違うのかも良くわからんけど。
とりあえず導入メモ。

インストール

  • pyreadlineと、ctypesをインストール。
  • Emacsのインストール先の etc\emacs.py を C:\Python24\Lib\site-packages\ あたりにコピー。

使い方

M-TAB 補完
C-c C-c バッファの内容を Python で実行
C-c C-r リージョンの内容を Python で実行
C-c C-s 任意の式を Python で実行
C-c C-z Python の出力を表示

JavaScript で HTML を Parse する

function parseHTML(text) {
    var createHTMLDocument = function() {
        var xsl = (new DOMParser()).parseFromString(
            ['<?xml version="1.0"?>',
             '<stylesheet version="1.0" xmlns="http://www.w3.org/1999/XSL/Transform">',
             '<output method="html"/>',
             '</stylesheet>'].join("\n"), "text/xml");

        var xsltp = new XSLTProcessor();
        xsltp.importStylesheet(xsl);
        var doc = xsltp.transformToDocument(
            document.implementation.createDocument("", "", null));
        return doc;
    };

    var doc = createHTMLDocument();
    var range = doc.createRange();
    doc.appendChild(doc.createElement("html"));
    range.selectNodeContents(doc.documentElement);
    doc.documentElement.appendChild(
        range.createContextualFragment(text));
    return doc;
}

こんな感じの function を定義しておくと

var doc = parseHTML(req.responseText);

な感じで HTML の DOM ツリーを取得できる。Firefox 1.5 と Opera 9.01 で動作を確認。

仮想関数の意義

  • 仮想関数の存在意義が良く分からない。ので使わないことにしよう。

ええと、Java を使える人がそういうこと言いますか。Javaのメソッドコールは全て動的束縛(仮想関数)だと思ったのだけども。まぁ、インスタンスの宣言型と実際の型を常に一致させている人はわかりにくいかもなぁ。
で、なんで仮想関数が必要かって

List list = new ArrayList();

とか、

Component component = new Button();

とかやりたい場面があるから。 あと、

public void foo(OutputStream out) {
    // do something
}

って感じに宣言しておくと、渡すインスタンスによって出力先はファイルやバイト配列やネットワークになると。静的束縛だけだとそう簡単にはいかない。

おまけ

vectorを使ってみる。Generics*1が使えるのでtypesafeっぽくていい感じ。

C++ の template と JavaGenerics って全然違うものなので、同一視するのはどうかと。
JavaGenerics は所詮コンパイル時の型チェックとキャストの自動挿入程度だけど、C++ の template はその名のとおり、template parameter ごとに実装が生成されるという恐ろしい仕組み。template meta programming といってこんなこともできる。

#include <iostream>

template<int n>
struct fact {
    enum {
        value = n * fact<n - 1>::value
    };
};

template<>
struct fact<1> {
    enum {
        value = 1
    };
};

int main()
{
    std::cout << fact<10>::value << std::endl;
    return 0;
}

あと、Java では無理な Duck Typing も template なら可能だったり。