1

この質問に続いて、ロードを呼び出すときのファイルスペックの奇妙なシンボルパス名で運を試してみましたが、ご覧のとおり失敗しました。以下は、説明できないエラーの例です。

このコードは機能しません:

(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))。あぁ...

4

1 に答える 1

1

もう 1 つの方法はTRUENAME、実際のファイル名を返す を使用することです。通常、これは違いはありません。

ファイル バージョンを使用してファイル システムをイメージ化します (VMS のファイル システムなど)。論理パス名がある場合foo:bar;baz.png.newest、たとえば、に変換される可能性があります/myfiles/images/baz.png~newest(ここでも、バージョン番号があると仮定してください)。これはまだ実際の物理ファイルではありません。そのような Lisp システムがファイルを開こうとすると、実際に最新のファイルを判別するためにファイル システムを調べる必要があります。そうかもしれません/myfiles/images/baz.png~42

そのため、実際の物理ファイル名を外部ツール (C ライブラリなど) に渡したい場合、論理パス名を展開するだけでは不十分な場合がありますが、実際の物理ファイルであるtruenameを計算する必要がある場合があります。

ファイル バージョンを処理する機能は、ファイル バージョンがITS、VMS、またはさまざまな Lisp マシン オペレーティング システムなどのオペレーティング システムで非常に一般的であった時代 (ファイル システムのバージョン管理を参照) に由来します。

これに関する主な実際的な問題は、さまざまな CL 実装のパス名操作に関する共通のテスト スイートがないことです。そのため、多くの細かい点で実装が異なります (特に、異なるオペレーティング システムの異なるファイル システムを処理する必要がある場合)。さらに、実際のファイル システムには複雑な問題があります。たとえば、Mac OS X のファイル名は、ウムラウトを処理するときに特別な Unicode エンコーディングを使用します。

于 2012-12-28T13:58:25.383 に答える