2018年6月21日木曜日

packageふたたび

 ソースを見ると、cl-dbiはdbiというpackageだった。

(defpackage dbi
  (:use :cl
 :dbi.error)
  (:nicknames :cl-dbi)
  (:import-from :dbi.driver
  :list-all-drivers
CL-USER> (cl-dbi::select "123")

; in: DBI::SELECT "123"
;     (DBI::SELECT "123")
; 
; caught STYLE-WARNING:
;   undefined function: DBI::SELECT
; 
; compilation unit finished
;   Undefined function:
;     DBI::SELECT
;   caught 1 STYLE-WARNING condition
; Evaluation aborted on #<UNDEFINED-FUNCTION SELECT {10065F6893}>.

 それに気づかずに、自分もdbiというpackageにしたら。

CL-USER> (defpackage dbi
  (:use :cl
 :cl-dbi)
  (:nicknames :keiba-dbi))

(in-package :keiba-dbi)

(defun select(sql)
  sql)
WARNING: DBI also uses the following packages:
  (DBI.ERROR)

【割愛】

  The ANSI Standard, Macro DEFPACKAGE
  The SBCL Manual, Variable *ON-PACKAGE-VARIANCE*
SELECT

 cl-cbiにselectが定義されてしまった。

DBI> (cl-dbi::select "123")
"123"
DBI>

 うわっ。
 これってcl-dbiを拡張してしまったってこと?1

 関数とか、conflictしたらどうするのよ、CommonLispって変、と一瞬、思ったのだけど2、よくよく考えたらC言語とかでも関数名がかぶったら片方が有効になるだけだった。
 そう思うと、javaの、あのディレクトリ構成にマップされた命名規則はconflictを避けるためのものなんだなぁ、といまさらながら。3

Footnotes:

1

プロンプトを見ると、何が起きたか、一目瞭然だった。

2

なんとなく、Lispってレキシカルって思った。

3

完全に避けることは不可能だろうけど。