in reply to 'print' puzzle

chipmunk and blakem are both correct - & also works here as well:
print &preprocess::scanfile ($ARGV[0]);

jeffa

L-LL-L--L-LL-L--L-LL-L--
-R--R-RR-R--R-RR-R--R-RR
F--F--F--F--F--F--F--F--
(the triplet paradiddle)

Replies are listed 'Best First'.
Re: (jeffa) Re: 'print' puzzle
by John M. Dlugosz (Monsignor) on Nov 13, 2001 at 00:13 UTC
    OK, so if it's a context problem, I can see that scanfile will see that it was called with "wantarray". But why does print think that's an indirect object, even with parens around it?

    —John

      Make sure that when you say "context", you're not thinking "scalar" and "list" context. Those don't apply here. Read on...
      print FOO $bar;
      Puts the contents of $bar on the filehandle FOO. We're all clear on that.
      print(FOO $bar);
      Does exactly the same thing in a nicely Perl 4-ish way. Perl's parser knows that the first argument to print (regardless of the parens) might be a filehandle which won't be comma-separated from the first thing to be printed. Now:
      print(Package::FOO $bar);
      Falls into the same trap. You're just specifying the package that the filehandle is in. The solutions:
      print +(Package::FOO $bar);
      The + tells the parser that the parens don't go with the print (and therefore the Package::FOO) and they're just grouping. So the parser isn't looking for a filehandle anymore. The Package::FOO gets used with indirect object syntax.
      print(Package::FOO($bar));
      The parser doesn't see a first-argument space-separated from the things to be printed and knows that Package::Foo is Something Else. (Later it'll know it's a function call.)
      print(&Package::FOO $bar);
      Same goes here, the parser doesn't see a filehandle here and knows that it shouldn't go looking here for one.

      I hope that helps. More importantly I hope my lack-of-sleep answer didn't cause more questions than answered...

        Yes that helps. You say that the parens don't affect it. The "if it looks like a function" rule tells it were the parameter list ends, but the determination that the first argument doesn't have a comma after it must come after that.

        So... why doesn't it know that's a function already? The module was "use"d, so it knows what's inside it.

      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

        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.