tags:

views:

386

answers:

5

I need to construct a file path inside a Perl script. Which path separator should I use to allow my script to work on both Windows and Unix?

Keep in mind that Windows needs a drive letter.

A: 

Q:Which path separator should I use to allow my script to work on both Windows and Unix?

A: /.

Explanation:
Windows can work similarly to Unix with / as path separator.
(Mac OS uses : as a path separator instead of /).

The File::Spec modules can also help.

    use File::Spec::Functions;
    chdir(updir());        # go up one directory
    $file = catfile(curdir(), 'temp', 'file.txt');
    # on Unix and Win32, './temp/file.txt'
    # on Mac OS, ':temp:file.txt'
    # on VMS, '[.temp]file.txt'

Source: 
http://www.xav.com/perl/lib/Pod/perlport.html
Mike
no, perl doesn't convert / (except on VMS, maybe?) - it just uses it, and it works fine in most Windows C library calls.
ysth
Your source is misguided and completely wrong.
brian d foy
@ysth, The / always works fine on my Windows, whereas \ sometimes causes problems. I thought my answer was to the point but it was downvoted so I'm becoming puzzled and I was trying to find support for my answer. Thanks for the comment. Whether Perl converts or not, it's possible that I'm misunderstanding the OP's question.
Mike
@brian, thanks for the comment. The source (dubious? wrong?) was quoted just to support my answer. Isn't it right that the / works both on Windows and Unix?
Mike
The new source is basically right, yes, though it appears to be an older copy of http://search.cpan.org/perldoc/perlport
ysth
@Mike: quoting random garbage from the internet doesn't make your answer any better than it was. It's better to find the real answer in the Perl documentation rather than rely on someone making up stuff based on something that accidently worked for them.
brian d foy
@brian, Thanks for commenting. Here's my thinking: Perl or whatever folks on different levels benefit from different things. For you, something might be garbage but for others, this something might be useful. I've read many of your answers and I believe I see one thing very clearly: no offense at all, sometimes because you obviously mis-estimated the question-poster's level /learning backgrounds, your answer appear quite irrelevant. But of course when a question is asked, it is open for interpretation and you just answered it your own way. Well, thanks for the comment again.
Mike
@brian, BTW, will you please avoid using argumentative word like "garbage" publicly, just neutral words like"outdated" or "irrelevant"? Although you're a Perl guru, it is kinda rude to call other people's stuff "garbage" publicly, isn't it?
Mike
I call garbage "garbage", including my own garbage. There's no neutrality when something is so woefully wrong as the first tripe that you posted. It deserves strong words to discourage other people from believing it and passing it on. You posted something you didn't understand and couldn't support as a guess. You posted garbage.
brian d foy
@Mike: If you post something publicly you should be prepared for it to be criticized -- possibly brutally. It's silly (and futile) to expect people to sugarcoat their responses. Programming forums are meritocracies, not popularity contests. Responses can be rather brusque but as a rule it's the *post* that's being criticized, not the author. Don't take it personally.
Michael Carman
@brian, the use of argumentative idiolect is not in accordance with the spirit of the SO. But "be torelant" is.
Mike
@Michael, Thanks for commenting. Different forums are different. I don't believe meritocracy is in the spirit of the SO but "be torelant" is. Brutal criticism is explicitly not the tradition of the SO but "be nice" is. Have you guys ever read the FAQ section? I'm puzzled.
Mike
@Michael and @brian, here's my understanding of the SO spirit: if we feel the impulse to criticize someone, we use constructive criticism. if we criticize constructively, we use neutral words. if we think something is self-evidently wrong, we let it rot away. if we think something's harmfully misleading, we point potential victims to good sources and provide solid reasons against it.
Mike
@Mike: The reputation system is a meritocracy (or at least an approximation of one). If you reread the comments impartially you'll find that brian only criticizes *what you wrote*, never *who you are.* That's not to say that his response couldn't have been better but constructive criticism doesn't require the use of kid gloves. Letting it rot isn't acceptable because the error isn't obvious to novices. (If you had known that the first source you quoted was wrong would you still have quoted it?) There's little point it trying to fix something completely wrong; hence the strong warning instead.
Michael Carman
@Michale, although I still don't agree with your on this, I appreciate your explanation. It has nothing to do with sugarcoating something. What I'm talking about is the priority of the use of neutral words in a tech forum. Humans are emotional. They pay more attention to the way you say it than what you say. When you use strong words, they are distracted, provoked, but not discouraged. Like I said, if we don't think something is self-evidently wrong, then provide solid logic against it, or, point potential victims to the worthwhile sources.
Mike
@Michael, @brian said he would also call his own stuff garbage and I think I understand what he meant. We may use S.O.B. or M.F. to call a real close friend, and it happens that African Americans use n.i.g**er to call each other. In those situations, teasing is meant and understood to increase intimacy between real friends. But we cannot misapply the situation. It's a tech forum where people are asked to avoid being arguementative and subjective like stated in the faq section.
Mike
+6  A: 

You want File::Spec. There are specific versions for Unix, Win32, and MacOS as well others.

s1n
You don't ever use the platform specific versions directly. You just need File::Spec. It figures out the rest for you.
brian d foy
I agree that you shouldn't use the specific versions, which is why my answer was just File::Spec with a little bit of extra information.
s1n
+1  A: 

It sounds like you are using path separator to mean the character between directory/file name components. But just in case you meant the other meaning:

Some things (notably environment variables like MANPATH or PERL5LIB) take a list of file or directory names, separated by a path separator character. Perl's Config module portably supplies such a character as $Config::Config{'path_sep'}.

ysth
+6  A: 

You want File::Spec's catpath:

       catpath()
         Takes volume, directory and file portions and returns an entire path.
         Under Unix, $volume is ignored, and directory and file are
         concatenated.  A '/' is inserted if need be.  On other OSes, $volume
         is significant.

             $full_path = File::Spec->catpath( $volume, $directory, $file );
brian d foy
+4  A: 

If you find File::Spec cumbersome, as I do, try Path::Class. It gives you directory and file objects to work with rather than having to call long winded File::Spec class methods on strings.

Schwern