sironekotoroの日記

Perl で楽をしたい

Perl つかって、macOS 上で Windows のパスを処理しようとして10分くらいハマる

たとえば h:\Dropbox\temp.jpg こんな感じのパスから temp.jpg という文字列を取り出したいと思いました。

Perl でパス処理、それも異なる OS 環境で!といったら標準モジュールの File::Spec です。

perldoc.jp

実際にはファイルにパスのリストが行区切りで書かれているのですが、簡略化するために直接パスを書いてみます。

最初に書いたのはこういう感じのコードでした。

#!/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 で書いてきたので、この問題にぶつからなかったんだなぁ。

本当にやりたいことはまだまだ先なのですが、まぁ、千里の道も一歩から。やっていきましょう。