A localizable interface to `select`

Have you ever forgotten to restore your original STDOUT (or other handle) when you want to select another one for a brief time? Does the usage

my $stdin = select *STDERR;
print "To STDERR";
select $stdin;

seem clunky?

I have always loved the interface provided by File::chdir. It gives you the $CWD variable. When you assign to it you change the working directory. Even better, if you do that with the local directive, you dynamically scope the change!

It struck me, while I was working on the test suite for another project, that I wished that I could have that same kind of interface to select. And why not, they both need changing and restoring of a global property? So I gave it a try, and lo and behold it was simple!

So here it goes, I present Tie::Select, which provides the $SELECT variable. Use it like this and I think you will wonder why you ever did it the other way!

 use Tie::Select;

 {
   local $SELECT = *STDERR;
   print "This goes to STDERR";
 }

 print "This goes to STDOUT";

13 Comments

I see the use of this module, but I find Tie::Select an awful name. The tie is an implementation detail, you shouldn’t expose that to your user. How about Handle::Select or something like that?

I prefer Local::Select. There’s not confusion with timezones and/or language because that is “Locale”, with a trailing “e”.

We’ve tried to reserve Local::* as a namespace that shouldn’t ever show up on CPAN so people can use it privately without conflicts.

I’d push for something in IO::Handle::*.

I admit it may be just preference, but I find Guard objects better (as in, it’s a generic way to automatically restore state) suited for such things:


    use strict;
    use Scope::Guard qw(guard); # or Guard, whichever

    sub foo {
           my $original = select *STDERR;
           my $guard = guard { select $original };
           .... do your thing ...
    }

    foo();
    # restored automatically. yey.

You don’t need Scope::Guard, lestrrat. SelectSaver has been in core forever.

FileHandle::Select

Heh. Sorry! I didn’t mean to obsolete your module. But yeah, knowing about both SelectSaver and Tie::Select, I don’t know what reason would compel me to use the latter. :-( Their semantics are identical, their surface syntaxes differ only superficially, but Tie::Select is an external dependency and its API consists of a global; I can’t think of a situation in which I’d pick it over SelectSaver.

Leave a comment

About Joel Berger

user-pic As I delve into the deeper Perl magic I like to share what I can.