モジュールシステム

理解が微妙なのでプログラミング Gauche の 20 章を見つつ。
頁数も少ないのでがっつりヤりたいんですが、どうなるか。

名前空間

ええと、微妙かもしれませんがローカルな束縛、を実現するためにモジュールシステムがある、という理解で良いのでしょうか。テキストで例示されているソレもそうした例になっている模様。
例示されているソレを試してみます。とりあえず sample1.scm を作成。

(define-module sample1
  (export addx))
(select-module sample1)

(define x 100)
(define (addx n)
  (+ n x))

(provide "sample1")

で、M-x run-gauche して以下。

gosh> (set! *load-path* (cons "." *load-path*))
("." "/usr/share/gauche/site/lib" "/usr/share/gauche/0.8.7/lib")
gosh> (require "sample1")
#<undef>
gosh> (import sample1)
#<undef>
gosh> (define x 1)
x
gosh> (addx 10)
110
gosh> 

テキスト見つつポイントを以下に。

  • define-module
    • body なナニで以下を記述との事
      • 使う module の export
      • 開示する名前の export
      • module の継承
    • export に渡す名前は列挙可能との事
    • 全部開示する場合は export-all 手続きが使えるげな
    • module の継承については別途との事
  • select-module
    • select-module 式が評価された後の手続きやマクロの定義は select-module に渡したモジュールの scope に閉じた束縛になる、はず
  • provide
    • require に対応との事
    • 何度も load を行なわないための仕組み

使う側

あるソースファイルに複数モジュールがある場合は

  • require でソースを読みこんで
  • import でモジュールを load

になる模様。ソースファイル名 == モジュール名なら use 構文が使えるとの事。use 構文が "/" をどう扱うか云々な記述があるが、現時点ではスルー。

って

テキスト読んでるとカレントディレクトリを *load-path* に加えるには add-load-path という手続きを使えば良いらしい。

継承

use ではなくて extend という構文を使えば export できるって書いてある。ちょっと変化球で以下を試してみました。
sample2.scm

(define-module sample2
  (export add2))
(select-module sample2)

(define (add1 n)
  (+ 1 n))

(define (add2 n)
  (add1 (add1 n)))

(provide "sample2")

sample3.scm

(define-module sample3
  (extend sample2)
  (export add100 add2))
(select-module sample3)

(define (add100 n)
  (+ 100 n))

(provide "sample3")

これで sample3 を use しても add1 は使えないはず。

gosh> (add-load-path ".")
("." "/usr/share/gauche/site/lib" "/usr/share/gauche/0.8.7/lib")
gosh> (use sample3)
#<undef>
gosh> add100
#<closure add100>
gosh> add2
#<closure add2>
gosh> (add2 2)
4
gosh> (add100 1)
101
gosh> add1
*** ERROR: unbound variable: add1
Stack Trace:
_______________________________________
gosh> 

なかなか面白い。最後の試験の部分も興味深いのですがかなり高度なチェックをしている模様。試しに上記の環境で試験してみた。

gosh> (use gauche.test)
#<undef>
gosh> (test-module 'sample3)
testing bindings in #<module sample3> ... ok
#<undef>
gosh> 

あと、その次の章のデバッグの項も掘り下げて見てみたい。
# 明日の予定ッス
なんとか Reading Gauche のやりクサしのソレをきちんと片付けたいデス。

追記

define-module とか select-module とかを disasm に渡してみたら toplevel じゃないと駄目、と叱られました。