$*CWD instead of chdir() and cwd()

421 views
Skip to first unread message

Michael G Schwern

unread,
Apr 15, 2005, 6:11:59 AM4/15/05
to perl6-l...@perl.org
I was doing some work on Parrot::Test today and was replacing this code
with something more cross platform.

# Run the command in a different directory
my $command = 'some command';
$command = "cd $dir && $command" if $dir;
system($command);

I replaced it with this.

my $orig_dir = cwd;
chdir $dir if $dir;
system $command;
chdir $orig_dir;

Go into some new directory temporarily, run something, go back to the
original.

Hmm. Set a global to a new value temporarily and then return to the
original value. Sounds a lot like local. So why not use it?

{
local chdir $dir if $dir;
system $command;
}

But localizing a function call makes no sense, especially if it has side
effects. Well, the current working directory is just a filepath. Scalar
data. Why have a function to change a scalar? Just change it directly.
Now local() makes perfect sense.

{
local $CWD = $dir if $dir;
system $command;
}

And this is exactly what File::chdir does. $CWD is a tied scalar.
Changing it changes the current working directory. Reading it tells you
what the current working directory is. Localizing it allows you to
safely change the cwd temporarily, for example within the scope of a
subroutine. It eliminates both chdir() and cwd().

Error handling is simple, a failed chdir returns undef and sets errno.

$CWD = $dir err die "Can't chdir to $dir: $!";

I encourage Perl 6 to adapt $*CWD similar to File::chdir and simply eliminate
chdir() and cwd(). They're just an unlocalizable store and fetch for global
data.

As a matter of fact, Autrijus is walking me through implementing it in Pugs
right now.

Larry Wall

unread,
Apr 15, 2005, 11:41:24 AM4/15/05
to perl6-l...@perl.org
On Fri, Apr 15, 2005 at 03:11:59AM -0700, Michael G Schwern wrote:
: Error handling is simple, a failed chdir returns undef and sets errno.

:
: $CWD = $dir err die "Can't chdir to $dir: $!";

Offhand, I guess my main semantic problem with it is that if a chdir
fails, you aren't in an undefined location, which the new value of $CWD
would seem to indicate. You're just where you were. Then the user
either has to remember that, or there still has to be some other
means of finding out the real location.

The other problem with it is the fact that people will assign relative
paths to it and expect to get the relative path back out instead
of the absolute path.

: I encourage Perl 6 to adapt $*CWD similar to File::chdir and simply eliminate


: chdir() and cwd(). They're just an unlocalizable store and fetch for global
: data.

Your assumption there is a bit inaccurate--in P6 you are allowed to
temporize (localize) the effects of functions and methods that are
prepared to deal with it. However, I agree that it's nice to have an
easily interpolatable value. So I think I'd rather see $CWD always
return the current absolute path even after failure, and

temp chdir($dir) err fail "Can't chdir to $dir: $!";

be made to work as a temporizable function at some point, via the TEMP
mechanism described in A4.

Larry

Michael G Schwern

unread,
Apr 15, 2005, 4:12:46 PM4/15/05
to perl6-l...@perl.org
Thus spake Larry Wall:

> Offhand, I guess my main semantic problem with it is that if a chdir
> fails, you aren't in an undefined location, which the new value of $CWD
> would seem to indicate. You're just where you were. Then the user
> either has to remember that, or there still has to be some other
> means of finding out the real location.

To be clear: Only the store operation will return undef on failure.
Additional fetches on $CWD will continue to return the cwd.

$CWD = '/path/which/exists';
$CWD = '/i/do/not/exist' err warn $!;
print $CWD;

This prints /path/which/exists/.


> The other problem with it is the fact that people will assign relative
> paths to it and expect to get the relative path back out instead
> of the absolute path.

I honestly never had this problem until I sat down and thought about it. :)
THEN I got all confused and started to do things like $CWD .= '/subdir';
instead of simply $CWD = 'subdir';. But the rule is simple and natural.
It takes a relative or absolute directory and ALWAYS returns an absolute
path. Lax in what inputs it accepts, strict in what it emits. This is no
more to remember than what chdir() and cwd() would do.

The result from $CWD would simply be a Dir object similar to Ken Williams'
Path::Class or Ruby's Dir object. One of the methods would be .relative.

I didn't bring up @CWD because I thought it would be too much in one sitting.
Basically it allows you to do this:

pop @CWD; # chdir ('..');
push @CWD, 'dir'; # chdir ('dir');
print $CWD[0]; # (File::Spec->splitdir(abs_path()))[0];
# ie. What top level directory am I in?

and all sorts of other operations that would normally involve a lot of
splitdir'ing.

And then there's %CWD which I'm toying with being a per-volume chdir like
you can do on Windows but that may be too much of a questionable thing.


> Your assumption there is a bit inaccurate--in P6 you are allowed to
> temporize (localize) the effects of functions and methods that are
> prepared to deal with it.

Yeah, we were talking about it on #perl6 a bit. That seems to me the more
bizarre idea than assigning to something which can fail. Localizing an
assignment is easy, there's just one thing to revert. But function calls can
do lots of things. Just how much does it reverse? I guess if its used
sensibly on sharp functions, such as chdir, and the behavior is
user-definable it can work but I don't know if the behavior will ever
be obvious for anything beyond the trivial.

FWIW my prompting to write File::chdir was a desire was for "local chdir".
So if "temp chdir" can be made to work that would solve most of the problem.

If nothing else perhaps chdir() should be eliminated and cwd() simply takes
an argument to make it a getter/setter.


> However, I agree that it's nice to have an
> easily interpolatable value. So I think I'd rather see $CWD always
> return the current absolute path even after failure

The problem there is it leaves $CWD without an error mechanism and thus
becomes an unverifiable operation. You have to use chdir() if you want to
error check and $CWD is reduced to a "scripting" feature.

It could throw an exception but then you have to wrap everything in a try
block. Unless Perl 6 is going this route for I/O errors in general I'd
rather not.

I'll give the error mechanism some more thought.


Anyhow, I encourage folks to play with File::chdir and see what they think
of the idea. I'm fixing up the Windows nits in the tests now.

Juerd

unread,
Apr 15, 2005, 5:52:38 PM4/15/05
to Michael G Schwern, perl6-l...@perl.org
Michael G Schwern skribis 2005-04-15 13:12 (-0700):

> To be clear: Only the store operation will return undef on failure.
> Additional fetches on $CWD will continue to return the cwd.

Still breaks

$ref = \($CWD = $foo);

I'm not sure this breakage matters, but if it breaks one thing, it's
likely to break more than just that one thing, and I wonder how much
attention this has been given.

Hm, but $CWD++ is nice! Especially if after photos9 it goes to photos10,
and not photot0. How does string ++ work in Perl 6, anyway?

> The problem there is it leaves $CWD without an error mechanism and thus
> becomes an unverifiable operation. You have to use chdir() if you want to
> error check and $CWD is reduced to a "scripting" feature.

Well, after failure it can be cwd() but false without breaking any real
code, because normally, you'd never if (cwd) { ... }, simply because
there's ALWAYS a cwd. If this is done, the thing returned by the STORE
can still be an lvalue and thus be properly reffed.

This would mean you'd use or instead of err, but I don't understand the
point of err meaning "error" together with the introduction of
true-but-false values anyway. Low-prec // should imo just be spelled
dor. But it's too late for that, of course.


Juerd
--
http://convolution.nl/maak_juerd_blij.html
http://convolution.nl/make_juerd_happy.html
http://convolution.nl/gajigu_juerd_n.html

Larry Wall

unread,
Apr 15, 2005, 6:04:52 PM4/15/05
to perl6-l...@perl.org
On Fri, Apr 15, 2005 at 01:12:46PM -0700, Michael G Schwern wrote:
: Thus spake Larry Wall:

: > Offhand, I guess my main semantic problem with it is that if a chdir
: > fails, you aren't in an undefined location, which the new value of $CWD
: > would seem to indicate. You're just where you were. Then the user
: > either has to remember that, or there still has to be some other
: > means of finding out the real location.
:
: To be clear: Only the store operation will return undef on failure.

That doesn't square with the notion that an assignment returns the
actual lvalue:

($new = $old) =~ s/foo/bar/;

: Additional fetches on $CWD will continue to return the cwd.


:
: $CWD = '/path/which/exists';
: $CWD = '/i/do/not/exist' err warn $!;
: print $CWD;
:
: This prints /path/which/exists/.

Except that the err should be looking at $CWD, not some other return value
of the assignment.

: > The other problem with it is the fact that people will assign relative


: > paths to it and expect to get the relative path back out instead
: > of the absolute path.
:
: I honestly never had this problem until I sat down and thought about it. :)
: THEN I got all confused and started to do things like $CWD .= '/subdir';
: instead of simply $CWD = 'subdir';. But the rule is simple and natural.
: It takes a relative or absolute directory and ALWAYS returns an absolute
: path. Lax in what inputs it accepts, strict in what it emits. This is no
: more to remember than what chdir() and cwd() would do.
:
: The result from $CWD would simply be a Dir object similar to Ken Williams'
: Path::Class or Ruby's Dir object. One of the methods would be .relative.
:
: I didn't bring up @CWD because I thought it would be too much in one sitting.
: Basically it allows you to do this:
:
: pop @CWD; # chdir ('..');
: push @CWD, 'dir'; # chdir ('dir');
: print $CWD[0]; # (File::Spec->splitdir(abs_path()))[0];
: # ie. What top level directory am I in?
:
: and all sorts of other operations that would normally involve a lot of
: splitdir'ing.
:
: And then there's %CWD which I'm toying with being a per-volume chdir like
: you can do on Windows but that may be too much of a questionable thing.

You could multiplex both the array and hash roles into the object
returned by $CWD, much like the $/ pattern match result object can
be subscripted as either $/[1] or $/<mantissa>. $CWD would itself
behave like a string in string context, but $CWD[] would get you to
the array value, and $CWD{} the hash value for systems that have
more than one current directory.

: > Your assumption there is a bit inaccurate--in P6 you are allowed to


: > temporize (localize) the effects of functions and methods that are
: > prepared to deal with it.
:
: Yeah, we were talking about it on #perl6 a bit. That seems to me the more
: bizarre idea than assigning to something which can fail. Localizing an
: assignment is easy, there's just one thing to revert. But function calls can
: do lots of things. Just how much does it reverse? I guess if its used
: sensibly on sharp functions, such as chdir, and the behavior is
: user-definable it can work but I don't know if the behavior will ever
: be obvious for anything beyond the trivial.

The function reverses whatever its TEMP property's closure knows how
to reverse. It's up to the function to know what its side effects are
and arrange to undo them.

: FWIW my prompting to write File::chdir was a desire was for "local chdir".


: So if "temp chdir" can be made to work that would solve most of the problem.
:
: If nothing else perhaps chdir() should be eliminated and cwd() simply takes
: an argument to make it a getter/setter.

If you're going to throw away the verb then the noun might as well be
a variable. But I like verbs for their readability, even if the verb
is "push". Note that "push" could be made to work with "temp" as well:

temp push $CWD, "subdir" err fail "..."

This would automatically pop $CWD at the end of the dynamic scope.

: > However, I agree that it's nice to have an


: > easily interpolatable value. So I think I'd rather see $CWD always
: > return the current absolute path even after failure
:
: The problem there is it leaves $CWD without an error mechanism and thus
: becomes an unverifiable operation. You have to use chdir() if you want to
: error check and $CWD is reduced to a "scripting" feature.

That was my point. And if you look back at what you wrote, you just
called $CWD an "operation". It's not--it's a noun. I like nouns,
but I also like verbs, and unlike in Perl 5 we don't have to rely on
the magical side effects of certain mystical nouns to do localization
any more.

But I don't understand what you mean by a "scripting" feature, or
how getting reduced to one is antithetical to a blissful existence.

: It could throw an exception but then you have to wrap everything in a try


: block. Unless Perl 6 is going this route for I/O errors in general I'd
: rather not.

We're not advocating mandatory exceptions unless you've said "use Fatal",
but I am asking for some consideration of the fact that verbs are often
expected to fail while nouns generally are not. This stemming from the
basic linguistic fact that verbs tend to be active while nouns tend to
be passive.

Larry

Juerd

unread,
Apr 15, 2005, 6:23:06 PM4/15/05
to chromatic, p6l
chromatic skribis 2005-04-15 15:18 (-0700):

> > Well, after failure it can be cwd() but false without breaking any real
> > code, because normally, you'd never if (cwd) { ... }, simply because
> > there's ALWAYS a cwd.
> Not always -- try removing a directory that's the pwd of another
> process.

Results in EPERM indeed :(

Chromatic

unread,
Apr 15, 2005, 6:18:55 PM4/15/05
to Juerd, p6l
On Fri, 2005-04-15 at 23:52 +0200, Juerd wrote:

> Well, after failure it can be cwd() but false without breaking any real
> code, because normally, you'd never if (cwd) { ... }, simply because
> there's ALWAYS a cwd.

Not always -- try removing a directory that's the pwd of another
process.

-- c

Michael G Schwern

unread,
Apr 15, 2005, 6:22:48 PM4/15/05
to Juerd, perl6-l...@perl.org
On Fri, Apr 15, 2005 at 11:52:38PM +0200, Juerd wrote:
> > becomes an unverifiable operation. You have to use chdir() if you want to
> > error check and $CWD is reduced to a "scripting" feature.
>
> Well, after failure it can be cwd() but false without breaking any real
> code, because normally, you'd never if (cwd) { ... }, simply because
> there's ALWAYS a cwd. If this is done, the thing returned by the STORE
> can still be an lvalue and thus be properly reffed.

Good idea!

Larry Wall

unread,
Apr 15, 2005, 8:55:51 PM4/15/05
to perl6-l...@perl.org
On Fri, Apr 15, 2005 at 03:22:48PM -0700, Michael G Schwern wrote:

But if cwd() or chdir() doesn't fail(), you probably won't get any
information on *why* the chdir failed in either the return value or $!.
That could be construed as antisocial.

In general I think "but" should be reserved for situations where the
original interface designer showed sufficient lack of imagination to
warrant such workarounds. That is how I treated all the RFCs that
made use of "but" for built-in functionality, and I haven't seen any
good reasons to alter my views on that. About the closest we get
to it is that "interesting values of undef" can be thought of as new
Exception(...) but undefined, or some such. But even that is usually
hidden behind the fail() predicate, and the undef role is probably
composed into exceptions in the first place. Or maybe it's the
other way around.

Larry

Michael G Schwern

unread,
Apr 15, 2005, 8:47:31 PM4/15/05
to Chip Salzenberg, perl6-l...@perl.org
On Fri, Apr 15, 2005 at 08:31:57PM -0400, Chip Salzenberg wrote:
> According to Michael G Schwern:

> > And this is exactly what File::chdir does. $CWD is a tied scalar.
>
> I don't think current directory maps well on a variable. That won't
> stop people from using it, of course. :-(
>
> There are several methods to determine the current directory. Each
> one has its corner cases, strengths and weaknesses (thus the
> proliferation of Cwd module functions), and it doesn't make any sense
> to me to elevate one over the rest through the proposed $CWD.

This is orthoginal to $CWD.

Perl 6 is going to have to decide on some sort of standard internal getcwd
technique, $CWD or not. In the same way that we have open() not fopen,
fdopen, freopen... we can choose the safest and most sensible technique for
determining the cwd and use that. You have to because when a new user asks
"how do I get the current working directory?" you want to say "cwd()" and
not "Well, there are a variety of different techniques..." Cwd.pm is a
perfect example of this problem. Which one should a user use? Most folks
just won't care and the micro-differences between the functions in Cwd.pm
aren't worth the trouble.

Present a sensible default. Write a module with all the other options for
those who need it.


> mkdir '/tmp/foo';
> $CWD = '/tmp/foo';
> rename '../foo', '../bar';
> say $CWD; # Well? Which is it?

Its exactly the same as...

mkdir '/tmp/foo';
chdir '/tmp/foo';
rename '../foo', '../bar';
say cwd();

Chip Salzenberg

unread,
Apr 15, 2005, 8:31:57 PM4/15/05
to Michael G Schwern, perl6-l...@perl.org
According to Michael G Schwern:
> And this is exactly what File::chdir does. $CWD is a tied scalar.

I don't think current directory maps well on a variable. That won't


stop people from using it, of course. :-(

There are several methods to determine the current directory. Each
one has its corner cases, strengths and weaknesses (thus the
proliferation of Cwd module functions), and it doesn't make any sense
to me to elevate one over the rest through the proposed $CWD.

mkdir '/tmp/foo';


$CWD = '/tmp/foo';
rename '../foo', '../bar';
say $CWD; # Well? Which is it?

--
Chip Salzenberg - a.k.a. - <ch...@pobox.com>
Open Source is not an excuse to write fun code
then leave the actual work to others.

Chip Salzenberg

unread,
Apr 15, 2005, 8:33:08 PM4/15/05
to chromatic, Juerd, p6l
According to chromatic:

Oh, the _directory_ is still there. :-)

Chip Salzenberg

unread,
Apr 15, 2005, 9:32:23 PM4/15/05
to Michael G Schwern, perl6-l...@perl.org
According to Michael G Schwern:
> On Fri, Apr 15, 2005 at 08:31:57PM -0400, Chip Salzenberg wrote:
> > There are several methods to determine the current directory.
>
> Perl 6 is going to have to decide on some sort of standard internal getcwd
> technique, $CWD or not.

I don't think Perl 6 "has" to do anything of the kind. It would
be a mistake to try.

> In the same way that we have open() not fopen, fdopen, freopen... we
> can choose the safest and most sensible technique for determining
> the cwd and use that.

"There's more than one sensible thing. There's more than one safe
thing."

And there is more than one open. Perl does have fopen/fdopen/freopen,
but they're accessed through other techniques besides the name of the
operator. For example, Perl spells C<fh = fdopen(5, "r")> as C<open
$fh, "<&=5"). The unique technique is there, just pushed out of the
operator name and into its parameters.

And then there's sysopen().

But open() is beside the point, no matter that it supports my point. :-)

As you know, under Unix, there's no such thing as "the current
directory" as a string. The only durable current directory is the
device and inode of C<stat('.')>. It's not wise to conflate the
current directory with a name that at some point in the past could
have been used to reach it.

> You have to because when a new user asks "how do I get the current

> working directory?" [...]

Then I answer him with the same patience I answer someone who asks
how to get the filename corresponding to an open file descriptor:
"There is no portable way. Tell me what you want to do, and maybe
I can help you."

Michael G Schwern

unread,
Apr 16, 2005, 1:53:38 AM4/16/05
to Chip Salzenberg, perl6-l...@perl.org
On Fri, Apr 15, 2005 at 09:32:23PM -0400, Chip Salzenberg wrote:
> > Perl 6 is going to have to decide on some sort of standard internal getcwd
> > technique, $CWD or not.
>
> I don't think Perl 6 "has" to do anything of the kind. It would
> be a mistake to try.

Sorry, I had assumed that having a "simple" cwd() was a forgone conclusion
so I just tried to bull through it. My bad. Lemme back up a few steps and
try again. [1]

Yes, there are lots of ways to check the cwd each filling in one edge
case or another. However I'd like to believe its possible to come up with
one simple, safe cwd() that works for 99.9% of the cases and call that cwd().
Then have a Cwd module full of all the various other techniques (or perhaps
attributes to alter the behavior of cwd()). This lets you answer the
question "How do I get the current working directory?" with "Short answer:
cwd(). Long answer: For this set of conditions, use this..."
This avoids the current state of things where a user with a simple
desire must slog through the rather daunting choices provided by Cwd.pm
and probably wind up making the wrong decision. [2] A high level language
really should smooth all that over.

How cwd() is implemented is not so important as what happens when it hits
an edge case. So maybe we can try to come up with a best fit cwd(). I'd
start by listing out the edge cases and what the possible behaviors are.
Maybe we can choose a set of behaviors which is most sensible across all
scenarios and define cwd() to act that way. Or maybe even just define what
various cwd variations currently do.

Here's the ones I know of off the top of my head. You probably know more.

* The cwd is deleted
* A parent directory is renamed
* A parent directory is a symlink


[1] http://angryflower.com/pathof.gif
[2] The state of Cwd.pm's docs add to my anxiety.

John Macdonald

unread,
Apr 16, 2005, 12:57:53 PM4/16/05
to Michael G Schwern, Chip Salzenberg, perl6-l...@perl.org
On Saturday 16 April 2005 01:53, Michael G Schwern wrote:
> How cwd() is implemented is not so important as what happens when it hits
> an edge case. So maybe we can try to come up with a best fit cwd(). I'd
> start by listing out the edge cases and what the possible behaviors are.
> Maybe we can choose a set of behaviors which is most sensible across all
> scenarios and define cwd() to act that way. Or maybe even just define what
> various cwd variations currently do.
>
> Here's the ones I know of off the top of my head. You probably know more.
>
> * The cwd is deleted
> * A parent directory is renamed
> * A parent directory is a symlink

There is also the possibility for permissions issues:

* You don't have permissions to determine cwd as an absolute pathname
* You are in a directory that you couldn't have chdir'ed into (that makes the
localized $CWD fail to return you to the original location when it goes out
of scope).

It's not hard to run a program that is setuid (to a non-root account) from within
a directory that is owner-only accessible.

Chip Salzenberg

unread,
Apr 16, 2005, 4:50:38 PM4/16/05
to Michael G Schwern, perl6-l...@perl.org
According to Michael G Schwern:
> Yes, there are lots of ways to check the cwd each filling in one edge
> case or another. However I'd like to believe its possible to come up with
> one simple, safe cwd() that works for 99.9% of the cases and call that cwd().

Well, it's certainly possible ... and it's not up to me, anyway; but I
still think it's a Bad Idea to standardize like that. I've already
said why (there's no good reason to pick one over another), though it
doesn't surprise me opinions differ. :-,

> A high level language really should smooth all that over.

An HLL or LLL, it doesn't really matter. This isn't a language
feature, this is an _operating_system_ feature. Pretending that the
system is providing an attribute that it really isn't just confuses
people in the long run.

> * The cwd is deleted
> * A parent directory is renamed
> * A parent directory is a symlink

s/parent/parent or current/g. Also:

* A parent or current directory is relocated entirely,
not just renamed within the same parent
* A parent or current directory has become unreadable
* Any of the above happens _during_ the execution of cwd(),
rather than beforehand

> [2] The state of Cwd.pm's docs add to my anxiety.

Sucker punch. :-)

Dave Whipp

unread,
Apr 16, 2005, 9:07:43 PM4/16/05
to perl6-l...@perl.org
Chip Salzenberg wrote:

> As you know, under Unix, there's no such thing as "the current
> directory" as a string. The only durable current directory is the
> device and inode of C<stat('.')>. It's not wise to conflate the
> current directory with a name that at some point in the past could
> have been used to reach it.

So can we make a stronger statement, and say that Perl6 won't think of
directories as strings, either. When you ask for a directory, it'll give
you an object. If you use one in string context then it will try its
best to give you a string that your OS might be able to use to access it
(or, thinking about cygwin, a string that a different OS might be able
to use...). But if it can't (e.g. when you access a directory relative
to one whose name it doesn't know), then it will fail.

A directory object could have a method to tell you if it thinks its
stringification is currently valid (i.e. if it can stat it and get the
same device+inode). It could also have a method that attempts obtain a
currently-valid name.

It'd also suggest that C<open> et al should be methods on a directory
object (default object for the global forms would be $*ENV.cwd)

And C<system>, C<exec>, C<qx> etc. shoul be methods on an "environment"
object, again defaulting to $*ENV. I should be able to do

my Env $env = $*ENV.clone;
$env.cwd ~= "/..";
$env.system("foo");

$env.fork might be interesting, too -- I'd expect it to set $*ENV = $env
in the child process. Which could be nice if an Env also has stdout,
stdin, etc. methods.

>>You have to because when a new user asks "how do I get the current
>>working directory?" [...]

How do you get the cwd? You call $*ENV.cwd. How to you get its name? You
use it in string context. (Of course, a new user probably won't think to
ask that second question: they'll print it, and it'll do what they
expect ... most of the time).

Chip Salzenberg

unread,
Apr 16, 2005, 11:28:27 PM4/16/05
to Dave Whipp, perl6-l...@perl.org
According to Dave Whipp:

> It'd also suggest that C<open> et al should be methods on a directory
> object (default object for the global forms would be $*ENV.cwd)

There is no system call "fd_relative_open". You can only open
relative to the current directory, not just any directory.[*] It'd be
mean to mislead people into thinking it was always available, but if
you put a big "this may not work!" on it, sure.

> How do you get the cwd? You call $*ENV.cwd. How to you get its name? You
> use it in string context.

No, that just hides the fact that you're still arbitrarily preferring
one method of getting the cwd.

[*] Using the fchdir() system call, you can get close, but it takes
three system calls instead of one; and if you have no fchdir(),
you're out of luck. Oh, and it's not thread-safe.

Johan Vromans

unread,
Apr 21, 2005, 2:22:29 AM4/21/05
to Chip Salzenberg, Michael G Schwern, perl6-l...@perl.org
Chip Salzenberg <ch...@pobox.com> writes:

> According to Michael G Schwern:

>> In the same way that we have open() not fopen, fdopen, freopen... we
>> can choose the safest and most sensible technique for determining
>> the cwd and use that.
>

> And there is more than one open. Perl does have fopen/fdopen/freopen,
> but they're accessed through other techniques besides the name of the
> operator. For example, Perl spells C<fh = fdopen(5, "r")> as C<open
> $fh, "<&=5"). The unique technique is there, just pushed out of the
> operator name and into its parameters.
> And then there's sysopen().

This is exactly the point (I think) Schwern is trying to make. There
is 'open', that will do most of the time. If a novice user asks how to
open a file, you can say "Well, just 'open $fh, $file'". If you want
more than vanilla file access, there are all the other forms of open
and open parameters.

From the perspective of 'current directory' there should also be a
simple and elegant way that will do in most cases. Advanced tricks can
be made possible using separate modules and such.

Maybe the basic problem is that 'current directory' is a system
dependent file system location that is not a fixed string, although it
usually can be represented as a string. Similar to a simple 'open', I
think the most common use of 'cwd' (or whatever) is to return a file
system location that can be returned to later, much in the sense of
'tell' and 'seek'. I think this can be implemented in a quite fail
safe way on most platforms.

-- Johan

Juerd

unread,
Apr 21, 2005, 8:03:53 AM4/21/05
to perl6-l...@perl.org
Johan Vromans skribis 2005-04-21 8:22 (+0200):

> This is exactly the point (I think) Schwern is trying to make. There
> is 'open', that will do most of the time. If a novice user asks how to
> open a file, you can say "Well, just 'open $fh, $file'". If you want
> more than vanilla file access, there are all the other forms of open
> and open parameters.

Just for the record, that's spelled $fh = open $file in Perl 6.

Larry Wall

unread,
Apr 21, 2005, 12:11:00 PM4/21/05
to perl6-l...@perl.org
On Thu, Apr 21, 2005 at 08:22:29AM +0200, Johan Vromans wrote:
: >From the perspective of 'current directory' there should also be a

: simple and elegant way that will do in most cases. Advanced tricks can
: be made possible using separate modules and such.

Yes, easy things should be easy, and hard things possible.

: Maybe the basic problem is that 'current directory' is a system


: dependent file system location that is not a fixed string, although it
: usually can be represented as a string. Similar to a simple 'open', I
: think the most common use of 'cwd' (or whatever) is to return a file
: system location that can be returned to later, much in the sense of
: 'tell' and 'seek'. I think this can be implemented in a quite fail
: safe way on most platforms.

I kinda like the proposed @CWD interface, insofar as it abstracts out
the most system-dependent part of the filename, the delimiter. Since
Perl 6 is throwing away $" in favor of a per-array property, that
property could simply be "/" for Unixish filenames. Then we can write
things like:

temp push @CWD, "subdir" err die "Can't chdir: $!";

I still think @CWD should try to track the actual directory you're
in though if some operation fails, which implies that the push above
is returning a reasonable result code, and whatever interface we give
for absolute navigation also has to return a reasonable result code,
which means it's not mere assignment. I think we can allow

@CWD = @SOMEDIR;

but that part of the interface probably needs to throw an exception
if it fails, since assignment must return @CWD. Or maybe there's some
way to hack it, but that seems kind of hackish.

One interesting thought. Since $" is turning into a property,
and since some directory schemes require varying delimiters, maybe
the $"-like property needs to be a list of delimiters, which you
repeat the last one of when you run out. So Windows might use <: />,
while VMS might use <[ ] /> or whatever it was, I forget. But this
would generalize to any array that needs varying delimiters in its
representation.

Larry

Reply all
Reply to author
Forward
0 new messages