in reply to Re: Re: Perl's Bad Ideas
in thread Perl's Bad Ideas

Says YuckFoo:
If $x is a filehandle, of course I am printing contents of $y to filehandle $x.
You seem to have missed the point here. That's probably my fault.

You said "If $x is a filehandle...". How can you tell if $x is a filehandle? (Answer: You can't.)

If Perl is smart enough to know it's a filehandle, why isn't it smart enough to use it as such?
Perl doesn't have any magic way to know it's a filehandle. That's why you have to leave off the comma. The missing comma says "By the way, this is a filehandle."

Let's try a slightly more concrete example:

$x = 'STDERR'; $y = "I like pie.\n" print $x, $y;
Now what?

--
Mark Dominus
Perl Paraphernalia

Replies are listed 'Best First'.
Re: Re: Perl's Bad Ideas
by belg4mit (Prior) on Apr 07, 2002 at 00:10 UTC
    It would have seemed to me the obvious behavior is to
    print 'STDERR', "I like pie.\n";
    to STDOUT. *However* fileno($x) returns 2. How uncool is that? I suppose you could ignore the cases where
    grep {$x eq $_ } 'STDIN', 'STDOUT', 'STDERR'
    And in all other cases you check fileno($x).

    --
    perl -pe "s/\b;([st])/'\1/mg"

      Says belg4mit:
      It would have seemed to me the obvious behavior is to
      print 'STDERR', "I like pie.\n";
      to STDOUT.
      Oh. So you're saying that there is no way to store a filehandle in a variable then. (Or at least, once you have, you can no longer print to it.) That seems to me like a somewhat bigger defect than having to omit a comma once in a while, but hey, if you say it's "obvious"...

      fileno($x) returns 2. How uncool is that?
      Well, of course it does. What did you think fileno STDERR was doing, anyway? STDERR is a bareword. You know what barewords do. fileno STDERR is the same as fileno 'STDERR' which is the same as fileno $x because $x contains STDERR.
      I suppose you could ignore the cases where
      grep {$x eq $_ } 'STDIN', 'STDOUT', 'STDERR'
      And in all other cases you check fileno($x).
      That makes no sense at all. You can't just 'ignore' the STDERR case; you have to do something. If you treat "STDERR" as a filehandle, it means you can't print the string STDERR to the standard output, which is a pretty serious defect. If you treat it as a string, it means you can't print anything to standard error. I don't think either of those is a very good choice.

      In other cases, you want to check fileno. Well, let's see what happens if you do that.

      sub foo { my ($code, $serial, $location) = @_; print "X", $code, "-", $serial, ": $location\n"; }
      This function works just fine, printing to stdout, until one day you forget and open a filehandle named X in some completely separate part of the program, and then suddenly the function is printing to filehandle X instead of to standard output. I don't think that was a very good choice either.

      Face it, if Larry had done anything as foolish as what you suggest, you guys wouldhave a lot more cause for complaint than you do with the missing comma.

      --
      Mark Dominus
      Perl Paraphernalia

        >Oh. So you're saying that there is no way to store a filehandle in a variable then. (Or at
        To which I say, you are getting what you ask for. If you want the contents of $x twice use the x operator.

        > but hey, if you say it's "obvious"...
        Please note I said *seemed* obvious. As in I was running through a thought process and then comparing against perl's actual behavior.

        >This function works just fine, printing to stdout, until one day you forget and open a
        >filehandle named X in some completely separate part of the program, and then suddenly
        This is not the same, it is not a scalar filehandle.

        UPDATE: This is a read-only value, clearly perl could be smart-enough to recognize that read-only values which are not STDERR, STDIN, or STDOUT as not a filehandle.

        perl -e '$a= \"a"; ${$a}.="s"; print ${$a}' Modification of a read-only value attempted at -e line 1.

        --
        perl -pe "s/\b;([st])/'\1/mg"