http://qs1969.pair.com?node_id=1092782

1s44c has asked for the wisdom of the Perl Monks concerning the following question:

I see a lot of references to how things would be easier if file handles had sigils. Is there some reason why they don't? Using references works great but mixing references with barewords for STDIN/OUT/ERR seems messy.

I'm sure this has been asked before but I could not find anything in the site search or with google.

Replies are listed 'Best First'.
Re: Why don't file handles have sigils? (*)
by tye (Sage) on Jul 09, 2014 at 02:58 UTC

    The sigil for file handles is *. That is also the sigil for "globs". But that sigil only works for global file handles. Lexical file handles are generally preferred these days. It so happens that lexical file handles were implemented by making this work:

    open my $fh, ...

    instead of making this work:

    my *FH; open *FH, ...

    likely because that required less work as far as making adjustments to the parser (and/or perhaps just because that is what popped into the implementer's head and seemed reasonable). Also, perhaps, because "globs" are symbol table thingies and lexicals don't go into any symbol table so "my *FH" is kind of "crossing the streams".

    That support appeared in 5.006_001 so you could maybe even find the implementer (and the discussion in p5p that lead to the change). (See "=head2 File and directory handles can be autovivified" in perl561delta.pod.)

    Update: Also because the precursors to proper lexical file handles were implemented w/o changes to Perl by people doing things like my $fh = do { local *FH; \*FH };.

    - tye        

Re: Why don't file handles have sigils?
by RonW (Parson) on Jul 08, 2014 at 20:13 UTC

    You could do this:

    my $fh; open($fh, ...);

    open will put a ref to an anonymous file handle into $fh. You can then use $fh anywhere a file handle can be used.

    (I think it actually puts in a File::IO object reference.)

    But I don't know why there isn't a sigil for file handles. Maybe Larry et al didn't want to dedicate a character for that?

      I do do that.

      I wasn't trying to say perl was wrong, just asking for enlightenment as to why it is the way it is.

        With so many ways to hang yourself, how could Perl be "wrong"? *grin*
Re: Why don't file handles have sigils?
by Anonymous Monk on Jul 08, 2014 at 20:08 UTC

    Q: why something perl

    A: Because :)

    I see a lot of references to how things would be easier if file handles had sigils.

    Where do you see them?

    I consider such stuff nonsense :)

    Things would be much easier, if only things worked the way I thought ... but then they'd be something else ; perl should really work the way I think, I shouldn't have to learn how it works

    A filehandle is just another $scalar

    Is there some reason why they don't?

    scalars are scalars, barewords are barewords ... which sigil would be used?

    There isn't a special sigil for objects, or a special sigil for integers, why should filehandles be so special?

    See below

    Using references works great but mixing references with barewords for STDIN/OUT/ERR seems messy.

    Maybe to noobs, you can always use typeglobs or typeglob references, \*STDIN, \*STDOUT, \*STDERR

    So there is a sigil for typeglobs, its as close as you can get ... STDIN/STDOUT/STDERR/DATA are the only bareword filehandles I use, the rest are $scalars (only available since perl 5.6.0, and yes, there was perl before 5.6.0 )

      Things would be much easier, if only things worked the way I thought ... but then they'd be something else ; perl should really work the way I think, I shouldn't have to learn how it works

      That's really not what I meant. I meant "why is it like that, is there some reason I don't know about?"

Re: Why don't file handles have sigils?
by trippledubs (Deacon) on Jul 09, 2014 at 00:46 UTC
    I wonder about this also. Annoying to kind of have to convert that in your head when reading older style instruction (Network Programming with Perl by Stein) that use barewords all over the place when the newer guidance is to use lexical filehandles. I think that the short answer is that the bareword is the old way to do it, and now you should use lexical variables because they limit the scope. This seems to confirm:
    #!/usr/bin/env perl use strict; use warnings; { open (OUTPUT,"> out.txt") or die; } print OUTPUT "a"; # Works OUTPUT must still be in scope { open (my $new_out, ">","new_out.txt") or die $!; print $new_out "b"; } #print $new_out "c"; #this will not work
      The future is here.
      open my $output, ">", "out.txt"; print $output "derp"; close $output;
Re: Why don't file handles have sigils?
by ikegami (Patriarch) on Jul 14, 2014 at 15:31 UTC

    Technically, they do. When you do

    open(FOO, '>', ...) or die $!; print(FOO "string\n");
    you are using a shortcuts for
    open(*FOO, '>', ...) or die $!; print({ *FOO } "string\n");

    *FOO is a typeglob, and typeglob use the "*" sigil except when made optional by certain operators.

Re: Why don't file handles have sigils?
by flowdy (Scribe) on Jul 13, 2014 at 12:09 UTC

    Why not think of STDIN, STDOUT and STDERR as a kind of constants? And really they look like nothing different, do they? Perl constants are used to be implemented as named subroutines with a zero-argument prototype, returning a filehandle reference.

    Unfortunately however, passing an actual user-defined constant filehandle to print() will work only when wrapped in curlies, likewise would any other expression returning a filehandle:

    use strict; sub FH () { open my $fh, '>', '/tmp/testfile.txt'; $fh } eval q{ print FH "Hello world!\n"; } or warn "Doesn't work - $@"; print {FH} "This works";

    The curlies are recommended best practice for every time you must use type-globs, cf. Conway(2006). Think of it as type-glob derefencing with the star sigil omitted again.

    Nowadays you should make lexical filehandles, how this is done has been already outlined in the thread.