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

I am trying to develope some networking functions that emulate the behavior of print and its likes using prototype.
It should work something like this:
myprint FILEHANDLE arguments
where FILEHANDLE is an optional.
Also no comma allowed after FILEHANDLE if there is one just like the defualt 'print'.

Would there be a way?
  • Comment on Is there a way to emulate 'print' using prototype?

Replies are listed 'Best First'.
Re: Is there a way to emulate 'print' using prototype?
by ikegami (Patriarch) on May 18, 2011 at 20:07 UTC

    No. You can make it work with barewords (in addition to scalars and whatnot), but the argument would be mandatory and would have to be followed by a comma.

    sub myprint(*@) { ... } myprint STDOUT, "foo", "bar";

      The indirect object calls allow you to omit the comma, but they are indirect object calls and you can't omit the object (the file-handle, in this case).

      An ordinary function call will allow you to examine the arguments and make whichever ones you want optional, but you won't be able to omit commas.

      The only way I know of to change perl's syntax, which is what you're asking, is with a source filter, which is not recommended as it tends to be fragile. If you say that this isn't changing the syntax (look at print), I'd say that print is a builtin, and thus its special handling is (by definition) part of the syntax, but myprint isn't, and doesn't get access to that syntax. I've not tried but you may be able to make a source filter work, mostly. I wouldn't.

        The indirect object calls allow you to omit the comma, but they are indirect object calls and you can't omit the object (the file-handle, in this case).

        I already mentioned indirect method call and its numerous limitations. The one you identified is easily worked around.

        The only way I know of to change perl's syntax, which is what you're asking, is with a source filter

        I've mentioned another in the post to which you replied, and another in this post.

        If you say that this isn't changing the syntax (look at print), I'd say that print is a builtin, and thus its special handling is (by definition) part of the syntax

        No, it's not part of the definition of builtins that they have special parsing rules.

Re: Is there a way to emulate 'print' using prototype?
by ikegami (Patriarch) on May 18, 2011 at 20:13 UTC

    Indirect method calls gets you pretty close:

    $ perl -E' sub IO::Handle::myprint { say "..."; } sub myprint { myprint STDOUT @_ } myprint STDOUT "foo"; myprint "foo"; eval q{ myprint(STDOUT "foo"); 1 } or warn $@; eval q{ myprint(\*STDOUT "foo"); 1 } or warn $@; eval q{ myprint { STDOUT } "foo"; 1 } or warn $@; eval q{ myprint { \*STDOUT } "foo"; 1 } or warn $@; ' syntax error at (eval 1) line 1, near "STDOUT "foo"" syntax error at (eval 2) line 1, near "*STDOUT "foo"" syntax error at (eval 3) line 1, near "} "foo"" syntax error at (eval 4) line 1, near "} "foo""

    (Some bits omitted from the error messages for readability.)

      Thank ikegami for your answer. So there is no direct way to do so:(
Re: Is there a way to emulate 'print' using prototype?
by Khen1950fx (Canon) on May 18, 2011 at 20:16 UTC
      Thanks. I was looking for this kind of the article :)
Re: Is there a way to emulate 'print' using prototype?
by Jenda (Abbot) on May 18, 2011 at 21:43 UTC

    What about using tie()d filehandles, select() and print and its likes? See Tie::Handle.

    Jenda
    Enoch was right!
    Enjoy the last years of Rome.

Re: Is there a way to emulate 'print' using prototype?
by ikegami (Patriarch) on May 18, 2011 at 20:23 UTC
      Thanks, I'll try Devel::Declare out.