この質問に続いて、ロードを呼び出すときのファイルスペックの奇妙なシンボルパス名で運を試してみましたが、ご覧のとおり失敗しました。以下は、説明できないエラーの例です。
このコードは機能しません:
(defun test-process-imgae-raw ()
(cl-gd:with-image-from-file
(test #P"digit-recognition:digit-7.png")
(process-image-raw test)))
これもありません:
(defun test-process-imgae-raw ()
(cl-gd:with-image-from-file
(test "digit-recognition:digit-7.png")
(process-image-raw test)))
しかし、このコードは次のことを行います。
(defun test-process-imgae-raw ()
(cl-gd:with-image-from-file
(test (translate-logical-pathname "digit-recognition:digit-7.png"))
(process-image-raw test)))
そして、これもそうです:
(defun test-process-imgae-raw ()
(cl-gd:with-image-from-file
(test (translate-logical-pathname #P"digit-recognition:digit-7.png"))
(process-image-raw test)))
ここに「翻訳者」があります:
(setf (logical-pathname-translations "DIGIT-RECOGNITION")
`(("**;*.*" "/home/wvxvw/Projects/digit-recognition/**/*.*")))
そして、ここに私が得ているエラーがあります:
Pathname components from SOURCE and FROM args to TRANSLATE-PATHNAME
did not match:
:NEWEST NIL
[Condition of type SIMPLE-ERROR]
Restarts:
0: [RETRY] Retry SLIME REPL evaluation request.
1: [*ABORT] Return to SLIME's top level.
2: [ABORT] Abort thread (#<THREAD "repl-thread" RUNNING {1003800113}>)
Backtrace:
0: (SB-IMPL::DIDNT-MATCH-ERROR :NEWEST NIL)
1: (SB-IMPL::TRANSLATE-COMPONENT :NEWEST NIL :NEWEST T)
2: (TRANSLATE-PATHNAME #P"DIGIT-RECOGNITION:DIGIT-7.PNG.NEWEST" #P"DIGIT-RECOGNITION:**;*.*" #P"/home/wvxvw/Projects/digit-recognition/**/*.*")
3: (TRANSLATE-LOGICAL-PATHNAME #P"DIGIT-RECOGNITION:DIGIT-7.PNG.NEWEST")
4: (SB-IMPL::QUERY-FILE-SYSTEM #P"DIGIT-RECOGNITION:DIGIT-7.PNG" :TRUENAME NIL)
5: (PROBE-FILE #P"DIGIT-RECOGNITION:DIGIT-7.PNG")
6: (CREATE-IMAGE-FROM-FILE #<unavailable argument> NIL)
7: (TEST-PROCESS-IMGAE-RAW)
translate-pathname の Hyperspec セクションを読み込もうとしていますが、そこに示されている例からも、その内容がまったく理解できません。ましてや、文字列をどのようなルールで変換してもエラーが発生する可能性があることさえ理解できません。これまでのところ、それは一方向の変換だけです...
この関数の SBCL ソースを読み取ろうとしていますが、非常に長く、この方法で問題を解明しようとすると膨大な時間がかかります。
tl;drtranslate-logical-pathname
ユーザーのコードから呼び出された場合、システム コードから呼び出された場合に、その関数から生成されるものとは異なるものを生成する可能性さえありますか? これは移植性がないだけでなく、完全に壊れています。
編集:
左側のパターンにもう 1 つアスタリスクを追加しますが、右側には追加しません。これは解決しました。しかし、なぜこれが必要なのかという目的や論理は、私には理解できません。
いえ
(setf (logical-pathname-translations "DIGIT-RECOGNITION")
`(("**;*.*.*" "/home/wvxvw/Projects/digit-recognition/**/*.*")))
これにより、パス名digit-recognition:foo.bar.newest
が成功するのと同じように許可さdigit-recognition:foo.bar
れますが、要件が私を超えているのはなぜですか。with-image-from-file
また、システム関数がパス名を指定されたものとはtranslate-logical-pathname
別のものに変更する権利があると感じるのはなぜですか?
EDIT2:
OK、これは の問題のようですcl-gd
。ファイル名を展開しようとするのではなく、文字どおりに受け取ります。create-image-from-file
おそらく私の質問に最もよく答えるから取られたこのコード:
(when (pathnamep file-name)
(setq file-name
#+:cmu (ext:unix-namestring file-name)
#-:cmu (namestring file-name)))
(with-foreign-object (err :int)
(with-cstring (c-file-name file-name)
(let ((image (ecase %type
((:jpg :jpeg)
(gd-image-create-from-jpeg-file c-file-name err))
つまり、実行する代わりに実行(namestring file-name)
する必要があります(namestring (trnaslate-logical-pathname file-name))
。あぁ...