Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

File::Spec::Win32 returning different result than File::Spec when doing catfile with empty string

by nysus (Parson)
on Sep 08, 2019 at 05:29 UTC ( [id://11105819]=perlquestion: print w/replies, xml ) Need Help??

nysus has asked for the wisdom of the Perl Monks concerning the following question:

Not sure if this is a bug or what. Running this on a mac but guessing results would be the same on *nix:

#! /usr/bin/env perl use strict; use warnings; use File::Spec::Win32; use File::Spec; my $nuts = File::Spec->catfile('blah', ''); print $nuts . "\n"; # prints "blah/" (note the slash) my $two_nuts = File::Spec::Win32->catfile('blah', ''); print $two_nuts . "\n"; # prints "blah" (no slash)

$PM = "Perl Monk's";
$MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate Priest Vicar";
$nysus = $PM . ' ' . $MCF;
Click here if you love Perl Monks

Replies are listed 'Best First'.
Re: File::Spec::Win32 returning different result than File::Spec when doing catfile with empty string
by jcb (Parson) on Sep 08, 2019 at 05:38 UTC

    Try giving a non-empty filename or if you really want a directory name, use the catdir method instead. If you want your code to be fully portable, you will need to carry directory names as arrays and only use catfile at the very end to actually produce a filename to give to the OS. But this may be overkill if you are sure that your code will never run on VMS or similar.

      Well, I want the trailing slash. It's needed in the context of my algorithm, currently. catdir on *nix does not create a trailing slash. I can recode my algorithm pretty easily but I thought it was weird that the same method produces two separate results.

      $PM = "Perl Monk's";
      $MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate Priest Vicar";
      $nysus = $PM . ' ' . $MCF;
      Click here if you love Perl Monks

        If you improve your algorithm to process directories as arrays of name components instead of copying back to strings, it will not be a problem any more and your algorithm should be faster, too.

        As for the odd behavior, I suspect that it was needed for portability to some oddball half-broken commercial Unix back in the 5.005 era. :-)

        Conceptually directory structures are trees, and paths are lists of nodes that represent traversal(1). When you think of things that way instead of strings with slashes, life becomes easier, and common tools tend to just work. Pushing to the boundaries of your application as much representational decoration as possible, and internally working with more native data structure types is a principal that doesn't only apply to data serialization formats, it also applies to filesystem paths.

        Your algorithm should be working with lists of directory names and file names, and converting to slash-delimited strings at the ingress and egress boundaries.

        (1) Actually many file systems are directed acyclic graphs, thanks to concepts such as hard linking, but conceptually we can treat them like heirarchical data structures, keeping in mind that it's possible for a node in the tree to point to any other node anywhere else in the tree. ...so the tree concept does sort of break down, but is a useful white lie.


        Dave

Re: File::Spec::Win32 returning different result than File::Spec when doing catfile with empty string
by haukex (Archbishop) on Sep 08, 2019 at 13:25 UTC

    This thread and your previous thread sound to me like you're leaning towards reinventing wheels instead of using File::Spec to its full potential. I might suggest that you explain what your algorithm is trying to do, and perhaps we can suggest a better approach.

      The algo just finds the greatest common relative directory to a group of files. Original code here. Current code is here.

      $PM = "Perl Monk's";
      $MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate Priest Vicar";
      $nysus = $PM . ' ' . $MCF;
      Click here if you love Perl Monks

        Here is a quick solution that took me less time to write again than it would have taken to find where I wrote this before:

        #!/usr/bin/perl use strict; use warnings; use File::Spec; # Note that test data is Unix-format! warn "Test data is in Unix format; may not work on $^O" unless File::Spec->isa('File::Spec::Unix'); my @Files = map {chomp; $_} (<DATA>); # find common prefix directories for a list of files; assuming that al +l # files are on the same volume, if the system has volumes sub common_prefix (@) { my @dirs = map {[File::Spec->splitdir((File::Spec->splitpath($_))[1] +)]} @_; my @prefix = @{shift @dirs}; foreach my $dir (@dirs) { for (my $i = 0; $i < @$dir && $i < @prefix; $i++) { splice @prefix, $i unless $dir->[$i] eq $prefix[$i] } } return @prefix } print "Sample files:\n"; print ' ',$_,"\n" for @Files; print "Common prefix:\n"; print ' ',File::Spec->catdir(common_prefix @Files),"\n"; __DATA__ /foo/bar/bax /foo/bar/baz /foo/baz/quux

        Sample output:

        Sample files: /foo/bar/bax /foo/bar/baz /foo/baz/quux Common prefix: /foo
Re: File::Spec::Win32 returning different result than File::Spec when doing catfile with empty string
by afoken (Chancellor) on Sep 09, 2019 at 18:47 UTC

    Related: File::Spec->case_tolerant() is broken - not just the code, but the design is broken. Maybe it won't bite you on Win32, but it will surely do on Linux and other Unixes (*BSD, MacOS X, Android, ...).

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
Re: File::Spec::Win32 returning different result than File::Spec when doing catfile with empty string
by Anonymous Monk on Sep 08, 2019 at 08:30 UTC

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11105819]
Approved by jcb
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (4)
As of 2024-03-28 20:00 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found