Path Separator and Windows

J

Justin Johnson

Using ruby 1.8.2 on Windows XP, the path separator used for things like
File.join is always / instead of \. Is there a way to force ruby to use
the correct path separator?

Thanks,
Justin
 
R

Robert Klemme

Justin Johnson said:
Using ruby 1.8.2 on Windows XP, the path separator used for things
like File.join is always / instead of \. Is there a way to force
ruby to use the correct path separator?

AFAIK Ruby can usually use both, so 'C:\\foo\\bar' and 'C:/foo/bar' are
equivalent. Btw, which Ruby version are you using? If it's the cygwin
version then slash definitively works,

Kind regards

robert
 
B

Bob Showalter

Justin said:
Using ruby 1.8.2 on Windows XP, the path separator used for things like
File.join is always / instead of \. Is there a way to force ruby to use
the correct path separator?

"correct" is debatable, since the Windows API accepts / as a separator.

Anyway, one approach you can use is:

File.join('foo','bar').gsub(File::SEPARATOR,
File::ALT_SEPARATOR || File::SEPARATOR)

On Win32 -> foo\bar
On *nix -> foo/bar
 
A

Austin Ziegler

Using ruby 1.8.2 on Windows XP, the path separator used for things like
File.join is always / instead of \. Is there a way to force ruby to use
the correct path separator?

Unless you're interacting with external programs, you don't need it to.

When you do, a simple .gsub(%r{/}) { "\\" } will do.

-austin
 
S

Stefan Lang

Using ruby 1.8.2 on Windows XP, the path separator used for things
like File.join is always / instead of \. Is there a way to force
ruby to use the correct path separator?

For ruby, "/" *is* the correct path separator. AFAIK, ruby
internally uses the slash as path separator on all platforms.

I recommend to use slashes and convert them to backslashes
when external programs are called. Perhaps a library can
help you; searching for "win" on RAA:

http://raa.ruby-lang.org/search.rhtml?search=win

Kind regards,
Stefan
 
A

Austin Ziegler

"correct" is debatable, since the Windows API accepts / as a separator.

Sort of. The base Win32 API does accept \ or /. However, the Unicode
Win32API -- which will be used in the future -- does not accept /.
Ruby, however, should continue to support both.

-austin
 
J

Justin Johnson

Bob said:
"correct" is debatable, since the Windows API accepts / as a separator.

Anyway, one approach you can use is:

File.join('foo','bar').gsub(File::SEPARATOR,
File::ALT_SEPARATOR || File::SEPARATOR)

On Win32 -> foo\bar
On *nix -> foo/bar

Is there a reason File::SEPARATOR isn't set to \ to begin with for
Windows? Even if the Windows API accepts a /, \ is standard for the
Windows command line and executing commands with / in paths passed as
args fails. Of course I can just do my own substitutions, but it seems
like this could be improved.

Thanks.
 
B

Bob Showalter

Justin said:
Is there a reason File::SEPARATOR isn't set to \ to begin with for
Windows? Even if the Windows API accepts a /, \ is standard for the
Windows command line and executing commands with / in paths passed as
args fails. Of course I can just do my own substitutions, but it seems
like this could be improved.

I'm not sure why it works the way it does; perhaps Matz will weigh in.
If you look at the source (file.c), the whole business is really quite
messy.

How did DOS (and then Windows) ever decide to use backslash I wonder?

And a pox on "drive letters" while we're at it! :)

The Unix approach seems so much more logical to me...
 
M

MenTaLguY

--=-mIJNd+4pGSWSV9p2F8wp
Content-Type: text/plain
Content-Transfer-Encoding: quoted-printable

How did DOS (and then Windows) ever decide to use backslash I wonder?

By the time they decided to add support for directories to DOS, / was
already in common use as an option specifier (similar to - on Unix).

-mental

--=-mIJNd+4pGSWSV9p2F8wp
Content-Type: application/pgp-signature; name=signature.asc
Content-Description: This is a digitally signed message part

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)

iD8DBQBDtGYCcUNIGiXCc4MRAl+2AKCw5u878Dco/cEweLVVXh7u/4EF0ACfaYDA
NENb9cSJQZunFxhWJhdXpmc=
=Y3sf
-----END PGP SIGNATURE-----

--=-mIJNd+4pGSWSV9p2F8wp--
 
D

Daniel Berger

Stefan said:
For ruby, "/" *is* the correct path separator. AFAIK, ruby
internally uses the slash as path separator on all platforms.

I recommend to use slashes and convert them to backslashes
when external programs are called. Perhaps a library can
help you; searching for "win" on RAA:

http://raa.ruby-lang.org/search.rhtml?search=win

Kind regards,
Stefan

Except that not all Windows functions accept '/' for a path separator.
So, if you happen to be passing the result of File.join to, say,
PathAppend using Win32API, it's going to fail.

If you definitely need backslashes then either take Austin's suggestion
and use gsub, or use the pathname2 package (on the RAA), which returns
a path with the "correct" separator. :)

Regards,

Dan
 
C

Chad Perrin

Is there a reason File::SEPARATOR isn't set to \ to begin with for
Windows?

I'm only guessing, but I suspect it has something to do with aiming for
cross-platform compatibility by default.
 
C

Chad Perrin

How did DOS (and then Windows) ever decide to use backslash I wonder?

Depending on how you look at it, I think it was either poor planning or
excellent planning. It's poor planning if you think the goal was to do
things "right", with future cross-platform compatibility in mind. It's
excellent planning if you think the goal was to hinder compatibility in
the future in the interests of fostering vendor lock-in.
 
R

Ross Bamford

I doubt it - they'd probably need to rewrite it (again).

Oh, sorry, you meant Ruby?

;)
I'm not sure why it works the way it does; perhaps Matz will weigh in.
If you look at the source (file.c), the whole business is really quite
messy.

How did DOS (and then Windows) ever decide to use backslash I wonder?

Protect, _never_ share, integration is evil. Back then, anyway. Maybe they
get it now.
And a pox on "drive letters" while we're at it! :)

The Unix approach seems so much more logical to me...

Me too, as I sit with my Laptop, homes and /usr/local mounted via NFS,
music playing from /dev/cdrom and my desktop just the way I like it - the
original roaming profile? AFAIR there aren't even any symlinks over in
winland, and local stuff _still_ gets mixed with the system...

(p.s. I don't want to argue with any Windows users, this is just
light-hearted jibing about a light-hearted OS ;> Used to use DOS myself,
time in the trenches, jumpers for goalposts, etc.)
 
J

John W. Kennedy

Bob said:
I'm not sure why it works the way it does; perhaps Matz will weigh in.
If you look at the source (file.c), the whole business is really quite
messy.

How did DOS (and then Windows) ever decide to use backslash I wonder?

And a pox on "drive letters" while we're at it! :)

The Unix approach seems so much more logical to me...

It was only with DOS 2.0 (1983) that they had the idea of trying to make
a Unix clone. DOS 1.x (1981) was a CP/M clone, which in turn was a
something-by-DEC clone. / was no longer available in 1983, because it
had already been established as the command-flag delimiter.

--
John W. Kennedy
"But now is a new thing which is very old--
that the rich make themselves richer and not poorer,
which is the true Gospel, for the poor's sake."
-- Charles Williams. "Judgement at Chelmsford"
 
K

Kellie Miller

------=_Part_4739_6243342.1135963229346
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

I'm not sure why it works the way it does; perhaps Matz will weigh in.
If you look at the source (file.c), the whole business is really quite
messy.

How did DOS (and then Windows) ever decide to use backslash I wonder?


To show my age :), I think the reason is historic. The original DOS file
system was stolen from CP/M. CP/M stole much of it's syntax from DEC
operating systems (RT-11 I think). In DEC operating systems, the '/'
character was used to introduce a switch.

And a pox on "drive letters" while we're at it! :)


Drive letters were also a hold over from DEC operating systems. I am not
really criticizing the DEC operating systems. They were way ahead of the
rest of the systems of there time until Unix arrived and changed the world.

The Unix approach seems so much more logical to me...As I said, Unix changed EVERYTHING.

cheers,
Kellie

------=_Part_4739_6243342.1135963229346--
 
J

Justin Johnson

Regardless of the history I am still of the opinion that something
should change. From this thread it seems that Ruby may have chosen to
use / everywhere to keep things consistent. Can anyone confirm that
this really is the decision? If so, it presents the following problems
for Windows users.

1) When a program displays paths back to users they all use / instead of
\ which isn't consistent with how the OS presents the paths to the user.
2) Trying to run a program in backticks for example with the paths using
/ fails.

I think a reasonable solution would be to allow the programmer to
configure how Ruby will behave, for example by allowing them to change a
global variable for the path separator. I figured this would be doable
but haven't found a way to do so yet. I also still think it makes more
sense to default to the line separater the OS uses, which is \ for
Windows regardless of what the API allows.

Anyone else agree with me on this? I'm not just complaining here. I'd
like to see Ruby improve but I want to make sure I'm not missing
something obvious.

Thanks for all the feedback.
Justin
 
A

Austin Ziegler

Regardless of the history I am still of the opinion that something
should change. From this thread it seems that Ruby may have chosen to
use / everywhere to keep things consistent. Can anyone confirm that
this really is the decision? If so, it presents the following problems
for Windows users.

1) When a program displays paths back to users they all use / instead
of \ which isn't consistent with how the OS presents the paths to
the user.

I don't personally see this as an issue. I might think that having a
method #localize for Pathname might be good that does the conversion for
you.
2) Trying to run a program in backticks for example with the paths
using / fails.

Then backticks, %x{}, and Kernel#system should probably look for / in
the command portion and change it to backslash.
I think a reasonable solution would be to allow the programmer to
configure how Ruby will behave, for example by allowing them to change
a global variable for the path separator. I figured this would be
doable but haven't found a way to do so yet. I also still think it
makes more sense to default to the line separater the OS uses, which
is \ for Windows regardless of what the API allows.

I disagree completely. Ruby's paths should always use '/' and the pieces
of Ruby which interact with the command-processor and/or the filesystem
should do the separator translation.

-austin
 
R

Ross Bamford

Anyone else agree with me on this? I'm not just complaining here. I'd
like to see Ruby improve but I want to make sure I'm not missing
something obvious.

Well, if I have to write my code to check path separators and work around
non standard stuff, it isn't going to happen. Granted using File.join and
so forth is always good practice but there are often times you need to
split a path manually or do some other kind of work on it. If all that
gets broken then I'm just not going to even try to fix it from this end.

I don't know, but I wonder how many others are writing code that's Windows
compatible by happy coincidence, purely because Ruby _works_ to give a
reasonably standard environment?

Just my opinion...
 
J

Johannes Friestad

I disagree completely. Ruby's paths should always use '/' and the pieces
of Ruby which interact with the command-processor and/or the filesystem
should do the separator translation.

-austin

I'm with Austin: Ruby paths should always use '/' and the translation
should be done by the pieces interacting with the system. This is what
Java does, and it's one of the nice things about Java.
The most important benefit is that you can write programs that run on
both Windows and Linux (and Mac and..) without the hassle of a lot of
'if current system is windows..' statements.

jf
 
J

Justin Johnson

Austin said:
I don't personally see this as an issue. I might think that having a
method #localize for Pathname might be good that does the conversion for
you.


Then backticks, %x{}, and Kernel#system should probably look for / in
the command portion and change it to backslash.

This seems like a reasonable solution to me.

1) Change backticks, %x{}, and Kernel#system to change slashes to
platform's path separator before running commands. Any other things
need this?
2) Add a method to Pathname??? to convert to platform's path separators
for convenience. Anything else need this?

Without at least #1 above it seems slightly broken to me (at least not
what one would expect), since you can have a path to an executable in a
Pathname but then you can't even run the command without doing a gsub on
it's string representation.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top