I have added the notes from Larry on prototyping to perlsub.pod;
they're somewhat succinct.
I did NOT add this:
Writers of C modules conversant with L<perlxs> might wish to consider
something like:
sv_setpv((SV*)newXS("POSIX::setlocale", XS_POSIX_setlocale, file), "$$");
sv_setpv((SV*)newXS("POSIX::sigaction", XS_POSIX_sigaction, file), "$$;$");
Because I'm not sure where it goes. (First patch may be dup)
--tom
*** pod/perlsub.pod Sun Mar 12 20:42:58 1995
--- npod/perlsub.pod Thu Dec 14 07:10:32 1995
***************
*** 112,118 ****
no outside module can see the subroutine, since its name is not in any
package's symbol table.
! =head2 Passing Symbol Table Entries
[.Note: The mechanism described in this section works fine in Perl 5, but
the new reference mechanism is generally easier to work with. See L<perlref>.]
--- 112,118 ----
no outside module can see the subroutine, since its name is not in any
package's symbol table.
! =head2 Passing Symbol Table Entries (typeglobs)
[.Note: The mechanism described in this section works fine in Perl 5, but
the new reference mechanism is generally easier to work with. See L<perlref>.]
***************
*** 205,210 ****
can treat undefined subroutine calls as calls to Unix programs.
There are mechanisms available for modules to help them split themselves
! up into autoloadable files to be used with the standard AutoLoader module.
! See the document on extensions.
--- 205,303 ----
can treat undefined subroutine calls as calls to Unix programs.
There are mechanisms available for modules to help them split themselves
! up into autoloadable files. See the standard AutoLoader module described
! in L<Autoloader>, the standard SelfLoader modules in L<SelfLoader>, and
! the document on adding C functions to perl code in L<perlxs>.
+ =head2 Prototypes
+
+ As of the 5.002 release of perl, if you declare
+
+ sub mypush (\@@)
+
+ then mypush takes arguments exactly like push does. Here are the
+ prototypes for some other functions that parse almost exactly like
+ the corresponding builtins.
+
+ Declared as Called as
+
+ sub mylink ($$) mylink $old, $new
+ sub myvec ($$$) myvec $var, $offset, 1
+ sub myindex ($$;$) myindex &getstring, "substr"
+ sub mysyswrite ($$$;$) mysyswrite $buf, 0, length($buf) - $off, $off
+ sub myreverse (@) myreverse $a,$b,$c
+ sub myjoin ($@) myjoin ":",$a,$b,$c
+ sub mypop (\@) mypop @array
+ sub mysplice (\@$$@) mysplice @array,@array,0,@pushme
+ sub mykeys (\%) mykeys %{$hashref}
+ sub myopen (*;$) myopen HANDLE, $name
+ sub mypipe (**) mypipe READHANDLE, WRITEHANDLE
+ sub mygrep (&@) mygrep { /foo/ } $a,$b,$c
+ sub myrand ($) myrand 42
+ sub mytime () mytime
+
+ Any backslashed prototype character must be passed something starting
+ with that character. Any unbackslashed @ or % eats all the rest of the
+ arguments, and forces list context. An argument represented by $
+ forces scalar context. An & requires an anonymous subroutine, and *
+ does whatever it has to to turn the argument into a reference to a
+ symbol table entry. A semicolon separates mandatory arguments from
+ optional arguments.
+
+ Note that the last three are syntactically distinguished by the lexer.
+ mygrep() is parsed as a true list operator, myrand() is parsed as a
+ true unary operator with unary precedence the same as rand(), and
+ mytime() is truly argumentless, just like time(). That is, if you
+ say
+
+ mytime +2;
+
+ you'll get mytime() + 2, not mytime(2), which is how it would be parsed
+ without the prototype.
+
+ The interesting thing about & is that you can generate new syntax with it:
+
+ sub try (&$) {
+ my($try,$catch) = @_;
+ eval { &$try };
+ if ($@) {
+ local $_ = $@;
+ &$catch;
+ }
+ }
+ sub catch (&) { @_ }
+
+ try {
+ die "phooey";
+ } catch {
+ /phooey/ and print "unphooey\n";
+ };
+
+ That prints "unphooey". (Yes, there are still unresolved
+ issues having to do with the visibility of @_. I'm ignoring that
+ question for the moment. (But note that if we make @_ lexically
+ scoped, those anonymous subroutines can act like closures... (Gee,
+ is this sounding a little Lispish? (Nevermind.))))
+
+ And here's a reimplementation of grep:
+
+ sub mygrep (&@) {
+ my $code = shift;
+ my @result;
+ foreach $_ (@_) {
+ push(@result, $_) if &$ref;
+ }
+ @result;
+ }
+
+ Some folks would prefer full alphanumeric prototypes. Alphanumerics have
+ been intentionally left out of prototypes for the express purpose of
+ adding named, formal parameters. The current mechanism's main goal is to
+ let module writers provide better diagnostics for module users. I fee the
+ notation quite understandable to Perl programmers, and that it will not
+ intrude greatly upon the meat of the module, nor make it harder to read.
+ The line noise is visually encapsulated into a small pill that's easy to
+ swallow.
+
+ This is all very powerful, of course, and should only be used in moderation
+ to make the world a better place.
they're somewhat succinct.
I did NOT add this:
Writers of C modules conversant with L<perlxs> might wish to consider
something like:
sv_setpv((SV*)newXS("POSIX::setlocale", XS_POSIX_setlocale, file), "$$");
sv_setpv((SV*)newXS("POSIX::sigaction", XS_POSIX_sigaction, file), "$$;$");
Because I'm not sure where it goes. (First patch may be dup)
--tom
*** pod/perlsub.pod Sun Mar 12 20:42:58 1995
--- npod/perlsub.pod Thu Dec 14 07:10:32 1995
***************
*** 112,118 ****
no outside module can see the subroutine, since its name is not in any
package's symbol table.
! =head2 Passing Symbol Table Entries
[.Note: The mechanism described in this section works fine in Perl 5, but
the new reference mechanism is generally easier to work with. See L<perlref>.]
--- 112,118 ----
no outside module can see the subroutine, since its name is not in any
package's symbol table.
! =head2 Passing Symbol Table Entries (typeglobs)
[.Note: The mechanism described in this section works fine in Perl 5, but
the new reference mechanism is generally easier to work with. See L<perlref>.]
***************
*** 205,210 ****
can treat undefined subroutine calls as calls to Unix programs.
There are mechanisms available for modules to help them split themselves
! up into autoloadable files to be used with the standard AutoLoader module.
! See the document on extensions.
--- 205,303 ----
can treat undefined subroutine calls as calls to Unix programs.
There are mechanisms available for modules to help them split themselves
! up into autoloadable files. See the standard AutoLoader module described
! in L<Autoloader>, the standard SelfLoader modules in L<SelfLoader>, and
! the document on adding C functions to perl code in L<perlxs>.
+ =head2 Prototypes
+
+ As of the 5.002 release of perl, if you declare
+
+ sub mypush (\@@)
+
+ then mypush takes arguments exactly like push does. Here are the
+ prototypes for some other functions that parse almost exactly like
+ the corresponding builtins.
+
+ Declared as Called as
+
+ sub mylink ($$) mylink $old, $new
+ sub myvec ($$$) myvec $var, $offset, 1
+ sub myindex ($$;$) myindex &getstring, "substr"
+ sub mysyswrite ($$$;$) mysyswrite $buf, 0, length($buf) - $off, $off
+ sub myreverse (@) myreverse $a,$b,$c
+ sub myjoin ($@) myjoin ":",$a,$b,$c
+ sub mypop (\@) mypop @array
+ sub mysplice (\@$$@) mysplice @array,@array,0,@pushme
+ sub mykeys (\%) mykeys %{$hashref}
+ sub myopen (*;$) myopen HANDLE, $name
+ sub mypipe (**) mypipe READHANDLE, WRITEHANDLE
+ sub mygrep (&@) mygrep { /foo/ } $a,$b,$c
+ sub myrand ($) myrand 42
+ sub mytime () mytime
+
+ Any backslashed prototype character must be passed something starting
+ with that character. Any unbackslashed @ or % eats all the rest of the
+ arguments, and forces list context. An argument represented by $
+ forces scalar context. An & requires an anonymous subroutine, and *
+ does whatever it has to to turn the argument into a reference to a
+ symbol table entry. A semicolon separates mandatory arguments from
+ optional arguments.
+
+ Note that the last three are syntactically distinguished by the lexer.
+ mygrep() is parsed as a true list operator, myrand() is parsed as a
+ true unary operator with unary precedence the same as rand(), and
+ mytime() is truly argumentless, just like time(). That is, if you
+ say
+
+ mytime +2;
+
+ you'll get mytime() + 2, not mytime(2), which is how it would be parsed
+ without the prototype.
+
+ The interesting thing about & is that you can generate new syntax with it:
+
+ sub try (&$) {
+ my($try,$catch) = @_;
+ eval { &$try };
+ if ($@) {
+ local $_ = $@;
+ &$catch;
+ }
+ }
+ sub catch (&) { @_ }
+
+ try {
+ die "phooey";
+ } catch {
+ /phooey/ and print "unphooey\n";
+ };
+
+ That prints "unphooey". (Yes, there are still unresolved
+ issues having to do with the visibility of @_. I'm ignoring that
+ question for the moment. (But note that if we make @_ lexically
+ scoped, those anonymous subroutines can act like closures... (Gee,
+ is this sounding a little Lispish? (Nevermind.))))
+
+ And here's a reimplementation of grep:
+
+ sub mygrep (&@) {
+ my $code = shift;
+ my @result;
+ foreach $_ (@_) {
+ push(@result, $_) if &$ref;
+ }
+ @result;
+ }
+
+ Some folks would prefer full alphanumeric prototypes. Alphanumerics have
+ been intentionally left out of prototypes for the express purpose of
+ adding named, formal parameters. The current mechanism's main goal is to
+ let module writers provide better diagnostics for module users. I fee the
+ notation quite understandable to Perl programmers, and that it will not
+ intrude greatly upon the meat of the module, nor make it harder to read.
+ The line noise is visually encapsulated into a small pill that's easy to
+ swallow.
+
+ This is all very powerful, of course, and should only be used in moderation
+ to make the world a better place.