Default filehandles, or topicalizing filehandles, or something

2007-05-01 Thread brian d foy
I was thinking about default filehandles yesterday. select() doesn't
seem to be around except as an Unfiled function in S16. 

Then, as I was looking at 

   .say( Hello World );

and 

   $ERR.say( Hello standard error );

I figured this might work, and does. Topicalizing a filehandle kinda
acts almost like a default filehandle:

   $_ = $*ERR;
   .say( Hello standard error );

But, of course, that won't work for say() used as a function:

   say Hello standard error ;

Then, I thought I might assign to $*OUT, which doesn't work in pugs
(and I might have missed the part of the spec that says these are
read-only):

   my $saved_standard = $*OUT;
   $*OUT = $*ERR;   # this is an error

   say This goes to stderr;   # not until previous line works   
   say $saved_standard: This goes to stdout;  # just fine

Is there going to be a Perl 6 feature for this?


Re: Default filehandles, or topicalizing filehandles, or something

2007-05-01 Thread Jonathan Lang

On 5/1/07, brian d foy [EMAIL PROTECTED] wrote:

I was thinking about default filehandles yesterday. select() doesn't
seem to be around except as an Unfiled function in S16.

Then, as I was looking at

   .say( Hello World );


At various times, I have seen something to the effect of each of the
following being bandied about:

 $*OUT.say( Hello World );
 Hello World.say;

That is, both filehandles and strings have 'say' methods that do
essentially the same thing, but using subtly different syntax.  How
would I use (Hello World.say) to write to filehandle $FH?  My gut
reaction would be to use an adverb for the purpose:

 Hello World.say :to($FH);

This would also work for the sub version:

 say :to($FH) Hello World;

With this in mind, you probably could create a localized alias for
'say', if you wanted to:

 {
   my say := OUTER::say.assuming(:to($FH));
   say Hello World; # same as 'say Hello World :to($FH);'
 }

The catch with this is that you'd have to do this for each output
routine separately.

How about this: Do the output routines default to the global
filehandles directly, or do they default to lexical bindings of them?
That is, does 'say' output to $*OUT in the absence of an explicit
filehandle, or does it output to $OUT (with the latter normally being
bound to $*OUT)?  If the latter, you should be able to redirect all of
your output in the rest of the current scope by saying:

 $OUT := $*ERR;

I can understand not being able to rebind the global filehandles.
After all: once they're rebound, how would you ever find what they
were originally bound to?

--
Jonathan Dataweaver Lang


Re: Default filehandles, or topicalizing filehandles, or something

2007-05-01 Thread Larry Wall
On Tue, May 01, 2007 at 09:26:38AM -0700, Jonathan Lang wrote:
: On 5/1/07, brian d foy [EMAIL PROTECTED] wrote:
: I was thinking about default filehandles yesterday. select() doesn't
: seem to be around except as an Unfiled function in S16.
: 
: Then, as I was looking at
: 
:.say( Hello World );
: 
: At various times, I have seen something to the effect of each of the
: following being bandied about:
: 
:  $*OUT.say( Hello World );
:  Hello World.say;
: 
: That is, both filehandles and strings have 'say' methods that do
: essentially the same thing, but using subtly different syntax.  How
: would I use (Hello World.say) to write to filehandle $FH?  My gut
: reaction would be to use an adverb for the purpose:
: 
:  Hello World.say :to($FH);
: 
: This would also work for the sub version:
: 
:  say :to($FH) Hello World;

Don't need a named arg, since we can simply be polymorphic on strings vs
filehandles, which thankfully do not overlap semantically:

Hello World.say($FH)
$FH.say(Hello World)

: With this in mind, you probably could create a localized alias for
: 'say', if you wanted to:
: 
:  {
:my say := OUTER::say.assuming(:to($FH));
:say Hello World; # same as 'say Hello World :to($FH);'
:  }
: 
: The catch with this is that you'd have to do this for each output
: routine separately.

You don't always want lexical scoping for this sort of thing; you
often want dynamic scoping instead.

: How about this: Do the output routines default to the global
: filehandles directly, or do they default to lexical bindings of them?
: That is, does 'say' output to $*OUT in the absence of an explicit
: filehandle, or does it output to $OUT (with the latter normally being
: bound to $*OUT)?  If the latter, you should be able to redirect all of
: your output in the rest of the current scope by saying:
: 
:  $OUT := $*ERR;
: 
: I can understand not being able to rebind the global filehandles.
: After all: once they're rebound, how would you ever find what they
: were originally bound to?

The plan introduced in A06 was to leave $*('IN'|'OUT'|'ERR') bound
to stdin, stdout, and stderr (which can still be dickered with on
the POSIXy level, of course), and instead emulate p5's select(FH)
using a global variable $*DEFOUT for the default handle of print
(and now say as well).

I note that $*DEFOUT didn't make it into any of the synopses (though it
did make it to pugs/t/builtins/io/say_and_print.t, oddly), so I've just
added it to pugs/docs/Spec/IO.pod, the proto-synopsis on IO.

Anyway, you should (eventually) just be able to say

{
temp $*DEFOUT := $MYFH;
foo();
}

to redirect the default output of foo() and then restore at the end of the
dynamic scope.  That's an improvement over dancing the select twostep.

Larry


Re: Default filehandles, or topicalizing filehandles, or something

2007-05-01 Thread Mark J. Reed

On 5/1/07, Larry Wall [EMAIL PROTECTED] wrote:

The plan introduced in A06 was to leave $*('IN'|'OUT'|'ERR') bound
to stdin, stdout, and stderr (which can still be dickered with on
the POSIXy level, of course), and instead emulate p5's select(FH)
using a global variable $*DEFOUT for the default handle of print
(and now say as well).


What about the default handle for warn/die?  $*DEFERR?

I think I prefer a more significant difference between the default
targets and the POSIXy std* values that they are initialized to,  like
the Ruby notion of using global variables initialized to named
constants, e.g. $stderr starts out as equal to STDERR but can be
reassigned...

--
Mark J. Reed [EMAIL PROTECTED]


Re: Default filehandles, or topicalizing filehandles, or something

2007-05-01 Thread Larry Wall
On Tue, May 01, 2007 at 01:41:45PM -0400, Mark J. Reed wrote:
: On 5/1/07, Larry Wall [EMAIL PROTECTED] wrote:
: The plan introduced in A06 was to leave $*('IN'|'OUT'|'ERR') bound
: to stdin, stdout, and stderr (which can still be dickered with on
: the POSIXy level, of course), and instead emulate p5's select(FH)
: using a global variable $*DEFOUT for the default handle of print
: (and now say as well).
: 
: What about the default handle for warn/die?  $*DEFERR?

Could certainly work it the same way.

: I think I prefer a more significant difference between the default
: targets and the POSIXy std* values that they are initialized to,  like
: the Ruby notion of using global variables initialized to named
: constants, e.g. $stderr starts out as equal to STDERR but can be
: reassigned...

Well, the question is, what does a subprocess get for fd(2) after
you do that?  I'd prefer to keep $*ERR nailed to fd(2) in general so
that modifying $*ERR actually changes the stderr of new subprocesses.
But that doesn't give you a method of indirection inside the current
process, so $*DEFERR would be a way to do that.  Forcing people
to use an explicit handle in that case would be another approach,
but certainly something like $*DEFERR would be kinder to embedding
systems that want to intercept such messages and log them.

Larry


Re: Default filehandles, or topicalizing filehandles, or something

2007-05-01 Thread Mark J. Reed

On 5/1/07, Larry Wall [EMAIL PROTECTED] wrote:

: I think I prefer a more significant difference between the default
: targets and the POSIXy std* values that they are initialized to,  like
: the Ruby notion of using global variables initialized to named
: constants, e.g. $stderr starts out as equal to STDERR but can be
: reassigned...

Well, the question is, what does a subprocess get for fd(2) after
you do that?  I'd prefer to keep $*ERR nailed to fd(2) in general so
that modifying $*ERR actually changes the stderr of new subprocesses.


Ah.  I had imagined $*ERR as a bit more ephemeral than that, with an
underlying really-real stderr.


But that doesn't give you a method of indirection inside the current
process, so $*DEFERR would be a way to do that.  Forcing people
to use an explicit handle in that case would be another approach,
but certainly something like $*DEFERR would be kinder to embedding
systems that want to intercept such messages and log them.


Right.  Something akin to P5's $SIG{__WARN__} and $SIG{__DIE__} would
also work, but that never seemed to be quite the right way to do that,
to me.

--
Mark J. Reed [EMAIL PROTECTED]


Re: Default filehandles, or topicalizing filehandles, or something

2007-05-01 Thread Larry Wall
On Tue, May 01, 2007 at 05:45:26PM -0400, Mark J. Reed wrote:
: Right.  Something akin to P5's $SIG{__WARN__} and $SIG{__DIE__} would
: also work, but that never seemed to be quite the right way to do that,
: to me.

Never seemed quite right to me either.  Er, except way back when it did... :/

In P6 such hooks are unnecessary for two reasons:

* Exception handlers are executed before the stack is unwound, so
a surrounding dynamic scope can get control at that point.

* Warnings are just exceptions that default to restarting, so the same
considerations apply.

And even if we did decide to install some kind of temporizable
global hook for such callbacks, I wouldn't put it into %SIG
these days.  I'm not even sure signals belong in %SIG anymore.
Seems to me they should just be event objects coming in via some
feed to the event-driven underbelly of the program, assuming
we go ahead with a unified events/threads model as suggested by
http://www.seas.upenn.edu/~lipeng/homepage/unify.html.

Larry