in reply to Perl appending \ or / based on windows or linux

Alternatively, use CORE module File::Spec, and let Perl handle it.


#11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

  • Comment on Re: Perl appending \ or / based on windows or linux

Replies are listed 'Best First'.
Re: Perl appending \ or / based on windows or linux
by jonadab (Parson) on Oct 07, 2014 at 11:00 UTC

    I second this.

    use File::Spec::Functions; my $path = catfile("xyzz", "qwen", "defs", "asd"); # $path is now "xyzz/qwen/defs/asd" on most systems, # but on Windows it'll have backslashes instead # and I think on old MacOS Classic systems it would # have colons or something. Don't ask about VMS.
Re^2: Perl appending \ or / based on windows or linux
by Anonymous Monk on Oct 07, 2014 at 19:20 UTC

    (Note: This is a reply equally to kennethk, jonadab, and anon)

    sravs448 wants to append a trailing slash (whether or not that's an XY Problem is another topic). Unfortunately, File::Spec, despite being the core module to handle file/pathnames properly and portably, does not provide a method to do this. Most likely that's because "append a trailing slash" is not really a portable concept across all these supported OSes.

    As long as the script is limited to a known set of OSes, McA's suggestion above is probably better in this case.

    If there was a solution with a core module (perhaps I've missed something*), that'd make me happy, since I've faced this problem myself before. (Back when I had this problem I didn't find a decent CPAN module either.)

      dasgar's point about regexing File::Spec aside, it seems like any application that requires a trailing directory separator is really just not using File::Spec enough. Maybe it's my lack of imagination, but short of this literal spec (as you say, XY Problem) I cannot come up with an appropriate use case.

      #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

        A couple of examples from a previous thread: The behavior of rsync sometimes depends on whether a pathname has a trailing slash or not. Often file patterns, such as in gitignore, will match only directories if there is a trailing slash on the name.

        However, as was argued in that thread, the forward slash is probably fine in all these applications, and so one solution when dealing with them might be File::Spec::Unix->catdir('foo','bar').'/'

        The only other actual use case I could come up with since then is displaying things to a user: a trailing directory separator makes it obvious that something is a path at first glance.

        So yeah, "I need a trailing slash" is more likely to be an XY Problem than a practical one...

      You should be able to use a combination of File::Spec and a regex to dynamically determine what the seperation character is - provided that the regex contains all possible seperation characters.

      use strict; use warnings; use File::Spec::Functions qw(:ALL); use feature 'say'; my $testpath = catdir('foo','bar'); #say $testpath; my $sepchar; ($sepchar) = ($testpath =~ m/(\\|\/)/); say $sepchar;

      Not sure that this is any better than using $^O to determine the seperation character, but it one possible method using a core module. In either case, you still need to know the valid seperation characters for OSes that you intend to support. I guess the only advantage of the code above over using $^O is that you don't need to know the values of $^O for each OS.

        Rather than matching the separation character, match the directory names:
        use strict; use warnings; use File::Spec::Functions qw(:ALL); use feature 'say'; my $testpath = catdir('foo','bar'); #say $testpath; my ($sepchar) = $testpath =~ m/^foo(.+)bar$/ or die 'Separation character identification failed'; say $sepchar;

        #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.