起動が重くなるのを何とかしたい話(その3)

また、コメントで教えてもらった所を見たら非常に参考になったのでメモ。

607 名前: 603 2005/09/14(水) 00:16:48 id:uLELS/sA0
>>606
それじゃあ長くなりますが貼ります。
大前提として user パッケージでない場合は "ed::" なり "lisp::" なりのプリフィックスが必要です。
ただし
1. user パッケージから use されているパッケージに登録されている
2. そのパッケージから export されている
の両方を満たせば、プリフィックスは必要ありません。

1. の方はデフォルトでは editor パッケージと lisp パッケージが当てはまります。
2. については各ファイルを見れば export コマンドのところに羅列してあるのでわかると思います。

注意しなければならないのは export されるのはそのファイルが読み込まれた時だということです。
たとえば autoload の場合、.xyzzy に書いておいても起動時にそのファイルが読み込まれることはありません。
長すぎると怒られたので続く↓

608 名前: 603 2005/09/14(水) 00:18:40 id:uLELS/sA0
たとえば
(autoload 'diff "diff")
(setq *diff-command-name* ...)
のような設定だけ .xyzzy に書いたとします。
*diff-command-name* は diff.l の中で export するように設定されているので
プリフィックスなしで使えるように見えますが、実際はうまくいきません。
これは xyzzy を起動するとき(.xyzzy を読み込むとき)に diff.l がまだ読み込まれていないので、
*diff-command-name* というシンボルがどこにも定義されておらず、
setq コマンドは新しいシンボルとして *diff-command-name* を user パッケージに登録してしまうからです。
この後実際に diff を起動しようとすると、その段階ではじめて diff.l が読み込まれ、
同時に *diff-command-name* というシンボルを editor パッケージに登録します。
そして export しようとしたところで先ほど user パッケージに登録されたシンボルと衝突するわけです。

あらかじめ ed:: をつけるなり (in-package "editor") と書くなりして editor パッケージに変数を登録しておけば
diff.l を読み込んだときにそのシンボルを見つけてくれるので衝突が回避できます。
また、require などで明示的にファイルを読み込んでおけば、export されたシンボルを
見つけることができるので、やはり衝突を回避できます。

最後に、見分け方としては *scratch* バッファに変数名を貼り付けて C-j してみれば、
変数がプリフィックスなしで使えるかわかりやすいと思います。

from http://makimo.to/2ch/pc7_software/1116/1116710824.html#607
中々参考になる話で、autoloadはレベル的にはrequireとかと同等と考えて問題ない様子。

■適当にまとめると
siteinit.lから他のファイルにかかれたlispを読み込むときにrequireを普通はしているわけだけど*1、そこでautoloadをrequireの代わりに使えば随時読み込みに成るんじゃないかと勝手に推測してみた。

  1. autoload:関数が呼び出された時点でファイルを読み込み(推測)
  2. require:必要ならば読み込み。既に読込済みであれば何もしません。
  3. load-library:requireと異なり、一度読んでいてももう一度読み込みます。

■名前の衝突とかの話は
単に関数とか変数の名前が被っているという話なので、変に勘違いしていなければ、そんなに気にしなくても良いような気がする。

■起動時の流れ
tips
http://www1.odn.ne.jp/ymtz/tips.html#boot
起動するときの流れはここら辺に詳しい。

■自分的な勘違いポイント
requireした上にautoloadをするみたいに考えるといつ読み込みをさせないようにするかのタイミングが意味不明だなぁとか思っていた(酷い勘違い)。同等のものと考えれば割とスッキリ。

*1:ネットインストーラを使っていると拡張したlispの呼び出しが別の所でまとめてrequiresされているんじゃないかと思うので見た目にはないかも