in reply to Re: (jeffa) Re: 'print' puzzle
in thread 'print' puzzle

I don't think perl is parsing that as an indirect object... it looks like perl interprets your print call as the two argument form: print FILEHANDLE LIST. I can emulate this with the following code:
#!/usr/bin/perl -wT use strict; package main; print Mymod::mysub (); package Mymod; sub mysub { '123' }
Which errors out with:
print() on unopened filehandle Mymod::mysub at ./parensubtest.pl line 5.

Interestingly enough, if you swap the two stanzas (move lines 7,8 above 4,5) the error disappears.

A similiar (but not identical) issue was discussed at Filehandles vs. Packages: And the winner is...

-Blake

Replies are listed 'Best First'.
Re: Re: Re: (jeffa) Re: 'print' puzzle
by John M. Dlugosz (Monsignor) on Nov 13, 2001 at 03:14 UTC
    What you call the "two argument form" is the "indirect object". You can have any number of arguments: print (x,y,z,1,2,3);. The "indirect object" is the special argument that doesn't have a comma after it.

    I agree, writing print Mymod::mysub (); will look like an indirect object per the node you refered to. But why does print (Mymod::sub ()); that is, with parens around it, do the same thing? That is the question I was asking.

      Parenthesis have nothing to do with it because of the way the Perl grammar is defined. From perly.y:
      LSTOP indirob argexpr /* print $fh @args */ FUNC '(' indirob expr ')' /* print ($fh @args */ LSTOP listexpr /* print @args */ FUNC '(' listexprcom ')' /* print (@args) */
      Looks like a typo in the second line, too.

      I'm not sure I agree that this is an "indirect object", though. It looks like the parser's trying to convert anything that looks like a filehandle into a filehandle.

        FUNC '(' indirob expr ')' /* print ($fh @args */
        Hmm, so it specifically allows parens there! I had no idea--I thought they would defeat this way of parsing.

        Also, is print special? I don't recall foo (bar (5)); ever trying to call bar->foo(5) instead.

        Is that why you don't agree that indirob is the right characterization for it?

        —John

      Ah, guess we we're talking about the same thing... I got confused when you said:
      I can see that scanfile will see that it was called with "wantarray" But why does print think that's an indirect object...
      But scanfile doesn't get treated as a subroutine at all, so I didn't understand where wantarrray comes in to play. See the second stanza below for what I thought you meant by indirect object...

      I don't have an answer for you, but I have yet to find a print statement that Deparses differently depending on the outer parens. I think it might be a red herring, which is why I left them off in my previous example.

      % perl -MO=Deparse -e 'print abc' print abc $_; % perl -MO=Deparse -e 'print(abc)' print abc $_; # when you said 'indirect object' I thought this was # what you thought was going on.... % perl -MO=Deparse -e 'print abc def' print 'def'->abc; % perl -MO=Deparse -e 'print(abc def)' print 'def'->abc; % perl -MO=Deparse -e 'open abc; print abc def' open abc; print abc 'def'; % perl -MO=Deparse -e 'open abc; print(abc def)' open abc; print abc 'def'; % perl -MO=Deparse -e 'print abc:: def' print abc 'def'; % perl -MO=Deparse -e 'print(abc:: def)' print abc 'def'; % perl -MO=Deparse -e 'print abc:: ()' print abc (); % perl -MO=Deparse -e 'print(abc:: ())' print abc (); % perl -MO=Deparse -e 'print abc::def ()' print abc::def (); % perl -MO=Deparse -e 'print(abc::def ())' print abc::def ();

      -Blake