Perl つかって、macOS 上で Windows のパスを処理しようとして10分くらいハマる
たとえば h:\Dropbox\temp.jpg
こんな感じのパスから temp.jpg
という文字列を取り出したいと思いました。
Perl でパス処理、それも異なる OS 環境で!といったら標準モジュールの File::Spec です。
実際にはファイルにパスのリストが行区切りで書かれているのですが、簡略化するために直接パスを書いてみます。
最初に書いたのはこういう感じのコードでした。
#!/usr/bin/env perl use strict; use warnings; use File::Spec; my $path = 'h:\Dropbox\temp.jpg'; my ( $volume, $directories, $file ) = File::Spec->splitpath($path); print $file . "\n"; # h:\Dropbox\temp.jpg
が、パースされずにそのまま出てきてしまいます。
うーん?
試しにMacのファイルでやってみると問題なくパースされます。
#!/usr/bin/env perl use strict; use warnings; use File::Spec; my $path = '~/Desktop/search.txt'; my ( $volume, $directories, $file ) = File::Spec->splitpath($path); print $file . "\n"; # search.txt
あれー、ちゃんと動いてるなーってことでドキュメント見てみます。
これらの関数はほとんどのオペレーティングシステムによって異なるので、 それぞれの OS 固有のルーチンは次のような別々のモジュールで利用可能です: File::Spec::Unix File::Spec::Mac File::Spec::OS2 File::Spec::Win32 File::Spec::VMS 現在の OS のための適切なモジュールは File::Spec によって自動的に 読み込まれます。 (VMS のような) 一部のモジュールはその OS でのみ利用可能な機能を 使っているので、全てのオペレーティングシステムで全てのモジュールが 読み込まれるわけではありません。
なるほど、手元の環境は mac なので、 macOS 用のモジュールが自動的に読み込まれる。そのモジュールで Windows のパス処理をしようとして失敗していたのか。
ってことで、以下のように変更して当初の目的を遂げたのでした。
#!/usr/bin/env perl use strict; use warnings; use File::Spec::Win32; # Windows のパスを処理するモジュールにした my $path = 'h:\Dropbox\temp.jpg'; my ( $volume, $directories, $file ) = File::Spec::Win32->splitpath($path); print $file . "\n"; # temp.jpg
思えば、今までは Windows で動かすコードは Windows 上で、Mac 上で動かすコードは Mac で書いてきたので、この問題にぶつからなかったんだなぁ。
本当にやりたいことはまだまだ先なのですが、まぁ、千里の道も一歩から。やっていきましょう。