Mailing List Archive

Pre-RFC: ${^OUTPUT_HANDLE}
Many items of perl interpreter state are exposed as scalar variables.
This allows you to temporarily change its value, perhaps by a `local`
or `dynamically` assignment:

{
local $, = " and ";
print @values;
}

The "currently selected output filehandle" as used by print/printf is
not so exposed; instead requiring the (honestly-bizarrely named)
select() dance:

{
my $oldh = select $newh;
print "Things"; # this goes to $newh;

select $oldh; # restore the old one.
}

This is bad because in the event of an exception, return, goto or
loopex, the previous value is not restored because that second select()
statement is never reached. This can't happen with the `local` or
`dynamically` assignments, because those are reliably restored even in
those events.

I propose the addition of a new perlvar; perhaps named

{
local ${^OUTPUT_HANDLE} = $newh;
print "Things";
}

to embody the same concept as the previous block involving two select()
expressions, but without that unreliability.


Thoughts?

Or maybe this is sufficiently small and uncontentious as to not bother
with writing an RFC and just go ahead and implement it?

--
Paul "LeoNerd" Evans

leonerd@leonerd.org.uk | https://metacpan.org/author/PEVANS
http://www.leonerd.org.uk/ | https://www.tindie.com/stores/leonerd/
Re: Pre-RFC: ${^OUTPUT_HANDLE} [ In reply to ]
On Fri, Oct 22, 2021 at 10:50 AM Paul "LeoNerd" Evans <
leonerd@leonerd.org.uk> wrote:

> Many items of perl interpreter state are exposed as scalar variables.
> This allows you to temporarily change its value, perhaps by a `local`
> or `dynamically` assignment:
>
> {
> local $, = " and ";
> print @values;
> }
>
> The "currently selected output filehandle" as used by print/printf is
> not so exposed; instead requiring the (honestly-bizarrely named)
> select() dance:
>
> {
> my $oldh = select $newh;
> print "Things"; # this goes to $newh;
>
> select $oldh; # restore the old one.
> }
>
> This is bad because in the event of an exception, return, goto or
> loopex, the previous value is not restored because that second select()
> statement is never reached. This can't happen with the `local` or
> `dynamically` assignments, because those are reliably restored even in
> those events.
>
> I propose the addition of a new perlvar; perhaps named
>
> {
> local ${^OUTPUT_HANDLE} = $newh;
> print "Things";
> }
>
> to embody the same concept as the previous block involving two select()
> expressions, but without that unreliability.
>
>
> Thoughts?
>
> Or maybe this is sufficiently small and uncontentious as to not bother
> with writing an RFC and just go ahead and implement it?
>

A similar mechanism is available for the similarly fatally-global chdir
function via the CPAN module https://metacpan.org/pod/File::chdir, and an
equivalent for select would be quite useful for the case where you want to
set it for a dynamic scope (affecting sub calls within the scope etc).
Perhaps worth prototyping on CPAN as that should be rather simple.

-Dan
Re: Pre-RFC: ${^OUTPUT_HANDLE} [ In reply to ]
On Fri, 22 Oct 2021 at 22:50, Paul "LeoNerd" Evans <leonerd@leonerd.org.uk>
wrote:

> I propose the addition of a new perlvar; perhaps named
>
> {
> local ${^OUTPUT_HANDLE} = $newh;
> print "Things";
> }
>

Wouldn't the existing STDOUT local() support be more clear for this case?
It also has the advantage of working equivalently for STDERR/warn:

{
local *STDOUT = $newh;
print "Redirected";
}
{
local *STDERR = $newh;
warn "Also redirected";
}

Or is this aimed more at format-related functionality?
Re: Pre-RFC: ${^OUTPUT_HANDLE} [ In reply to ]
On Fri, Oct 22, 2021 at 11:12 AM Tom Molesworth via perl5-porters <
perl5-porters@perl.org> wrote:

> On Fri, 22 Oct 2021 at 22:50, Paul "LeoNerd" Evans <leonerd@leonerd.org.uk>
> wrote:
>
>> I propose the addition of a new perlvar; perhaps named
>>
>> {
>> local ${^OUTPUT_HANDLE} = $newh;
>> print "Things";
>> }
>>
>
> Wouldn't the existing STDOUT local() support be more clear for this case?
> It also has the advantage of working equivalently for STDERR/warn:
>
> {
> local *STDOUT = $newh;
> print "Redirected";
> }
> {
> local *STDERR = $newh;
> warn "Also redirected";
> }
>
> Or is this aimed more at format-related functionality?
>

Replacing superglobals wholesale is a bit different from select, which
still would allow you to print to STDOUT while selecting a different
default handle.

-Dan
Re: Pre-RFC: ${^OUTPUT_HANDLE} [ In reply to ]
On Fri, 22 Oct 2021 23:11:38 +0800
Tom Molesworth via perl5-porters <perl5-porters@perl.org> wrote:

> On Fri, 22 Oct 2021 at 22:50, Paul "LeoNerd" Evans
> <leonerd@leonerd.org.uk> wrote:
>
> > I propose the addition of a new perlvar; perhaps named
> >
> > {
> > local ${^OUTPUT_HANDLE} = $newh;
> > print "Things";
> > }
> >
>
> Wouldn't the existing STDOUT local() support be more clear for this
> case? It also has the advantage of working equivalently for
> STDERR/warn:
>
> {
> local *STDOUT = $newh;
> print "Redirected";
> }
> {
> local *STDERR = $newh;
> warn "Also redirected";
> }
>
> Or is this aimed more at format-related functionality?

Wow. I had actually forgotten you can do that.

Turns out that's perfectly fine for my use-case, which was a small
unit-test around a print'ing method. I shall do that instead.


The prosecution rests, your Honour.

--
Paul "LeoNerd" Evans

leonerd@leonerd.org.uk | https://metacpan.org/author/PEVANS
http://www.leonerd.org.uk/ | https://www.tindie.com/stores/leonerd/
Re: Pre-RFC: ${^OUTPUT_HANDLE} [ In reply to ]
* Paul "LeoNerd" Evans <leonerd@leonerd.org.uk> [2021-10-22 16:19:29 +0100]:

> On Fri, 22 Oct 2021 23:11:38 +0800
> Tom Molesworth via perl5-porters <perl5-porters@perl.org> wrote:
>
> > On Fri, 22 Oct 2021 at 22:50, Paul "LeoNerd" Evans
> > <leonerd@leonerd.org.uk> wrote:
> >
> > > I propose the addition of a new perlvar; perhaps named
> > >
> > > {
> > > local ${^OUTPUT_HANDLE} = $newh;
> > > print "Things";
> > > }
> > >
> >
> > Wouldn't the existing STDOUT local() support be more clear for this
> > case? It also has the advantage of working equivalently for
> > STDERR/warn:
> >
> > {
> > local *STDOUT = $newh;
> > print "Redirected";
> > }
> > {
> > local *STDERR = $newh;
> > warn "Also redirected";
> > }
> >
> > Or is this aimed more at format-related functionality?
>
> Wow. I had actually forgotten you can do that.
>
> Turns out that's perfectly fine for my use-case, which was a small
> unit-test around a print'ing method. I shall do that instead.
>
>
> The prosecution rests, your Honour.

If the net effect is that you can more clearly make a current script
"print" into different file handle by redefining what's used implicitly
via C<print> (STDOUT) or C<warn> (STDERR), then that might be handy.

I've also run into required gymnastics when wanting to both pipe STDIN
into a script *and* provide a means for interactive input, e.g.:

% ./dostuff.pl < input.file

and dostuff.pl *wants* to be able to have the following,

while (<>) {
# do something with $_
...
print "found X, proceed? (Y/n)\n";
my $ans = <STDIN>;
...
}

Anyway, just a thought. I might have read this whole thread wrong so pardon
me if I did.

Cheers,
Brett

>
> --
> Paul "LeoNerd" Evans
>
> leonerd@leonerd.org.uk | https://metacpan.org/author/PEVANS
> http://www.leonerd.org.uk/ | https://www.tindie.com/stores/leonerd/

--
--
oodler@cpan.org
oodler577@sdf-eu.org
SDF-EU Public Access UNIX System - http://sdfeu.org
irc.perl.org #openmp #pdl #native
Re: Pre-RFC: ${^OUTPUT_HANDLE} [ In reply to ]
On Fri, 22 Oct 2021 at 16:50, Paul "LeoNerd" Evans <leonerd@leonerd.org.uk>
wrote:

> The "currently selected output filehandle" as used by print/printf is
> not so exposed; instead requiring the (honestly-bizarrely named)
> select() dance:
>
> {
> my $oldh = select $newh;
> print "Things"; # this goes to $newh;
>
> select $oldh; # restore the old one.
> }
>
>
Alternative approach:
{
local select $newh;
print "Things";
}
Re: Pre-RFC: ${^OUTPUT_HANDLE} [ In reply to ]
On Fri, Oct 22, 2021 at 04:19:29PM +0100, Paul "LeoNerd" Evans wrote:
> On Fri, 22 Oct 2021 23:11:38 +0800
> Tom Molesworth via perl5-porters <perl5-porters@perl.org> wrote:

> > Wouldn't the existing STDOUT local() support be more clear for this
> > case? It also has the advantage of working equivalently for
> > STDERR/warn:
> >
> > {
> > local *STDOUT = $newh;
> > print "Redirected";
> > }
> > {
> > local *STDERR = $newh;
> > warn "Also redirected";
> > }
> >
> > Or is this aimed more at format-related functionality?
>
> Wow. I had actually forgotten you can do that.

"Me too".

(Actually, for me, it's more "I hadn't realised that this would work")

> Turns out that's perfectly fine for my use-case, which was a small
> unit-test around a print'ing method. I shall do that instead.

I wondered - as it doesn't seem to be "obvious", should we document this?

I'm proposing https://github.com/Perl/perl5/pull/19225

(and now we see whether the cygwin CI test fails on a docpatch)

Nicholas Clark
Re: Pre-RFC: ${^OUTPUT_HANDLE} [ In reply to ]
On Fri, Oct 22, 2021 at 11:02 AM Dan Book <grinnz@gmail.com> wrote:

> On Fri, Oct 22, 2021 at 10:50 AM Paul "LeoNerd" Evans <
> leonerd@leonerd.org.uk> wrote:
>
>> Many items of perl interpreter state are exposed as scalar variables.
>> This allows you to temporarily change its value, perhaps by a `local`
>> or `dynamically` assignment:
>>
>> {
>> local $, = " and ";
>> print @values;
>> }
>>
>> The "currently selected output filehandle" as used by print/printf is
>> not so exposed; instead requiring the (honestly-bizarrely named)
>> select() dance:
>>
>> {
>> my $oldh = select $newh;
>> print "Things"; # this goes to $newh;
>>
>> select $oldh; # restore the old one.
>> }
>>
>> This is bad because in the event of an exception, return, goto or
>> loopex, the previous value is not restored because that second select()
>> statement is never reached. This can't happen with the `local` or
>> `dynamically` assignments, because those are reliably restored even in
>> those events.
>>
>> I propose the addition of a new perlvar; perhaps named
>>
>> {
>> local ${^OUTPUT_HANDLE} = $newh;
>> print "Things";
>> }
>>
>> to embody the same concept as the previous block involving two select()
>> expressions, but without that unreliability.
>>
>>
>> Thoughts?
>>
>> Or maybe this is sufficiently small and uncontentious as to not bother
>> with writing an RFC and just go ahead and implement it?
>>
>
> A similar mechanism is available for the similarly fatally-global chdir
> function via the CPAN module https://metacpan.org/pod/File::chdir, and an
> equivalent for select would be quite useful for the case where you want to
> set it for a dynamic scope (affecting sub calls within the scope etc).
> Perhaps worth prototyping on CPAN as that should be rather simple.
>

I was informed this exists already on CPAN:
https://metacpan.org/pod/Tie::Select

-Dan
Re: Pre-RFC: ${^OUTPUT_HANDLE} [ In reply to ]
On Tue, 9 Nov 2021 16:55:49 +0000
Nicholas Clark <nick@ccl4.org> wrote:

> I'm proposing https://github.com/Perl/perl5/pull/19225
>
> (and now we see whether the cygwin CI test fails on a docpatch)

There's now a merge conflict because of some unrelated changes in the
files around it. I've fixed that up, and also added some more words to
address khw's comment:

https://github.com/leonerd/perl5/tree/local-STDOUT-instead-of-select

Shall I make a new PR and migrate that across, or do you want to update
your branch from it? (I don't think github lets you change the source
branch of a PR)

--
Paul "LeoNerd" Evans

leonerd@leonerd.org.uk | https://metacpan.org/author/PEVANS
http://www.leonerd.org.uk/ | https://www.tindie.com/stores/leonerd/