GSP
Quick Navigator

Search Site

Unix VPS
A - Starter
B - Basic
C - Preferred
D - Commercial
MPS - Dedicated
Previous VPSs
* Sign Up! *

Support
Contact Us
Online Help
Handbooks
Domain Status
Man Pages

FAQ
Virtual Servers
Pricing
Billing
Technical

Network
Facilities
Connectivity
Topology Map

Miscellaneous
Server Agreement
Year 2038
Credits
 

USA Flag

 

 

Man Pages
Perl6::Subs(3) User Contributed Perl Documentation Perl6::Subs(3)

Perl6::Subs - Define your subroutines in the Perl 6 style

Version 0.05

  use Perl6::Subs;

  sub foo ($x)                     # Positional parameters
    { bar($x) }

  sub get (Array $x)               # Type validation
    { pop @$x }

  sub get_or_die ($x of Array where { @$_ })  # Subtyping
    { pop @$x }

  sub show (Str $s, IO ?$io)       # Optional parameters
    { print { $io || *STDOUT } $s }

  sub limit (Int $i, Int +$hi, Int +$low)  # Named parameters
    { ... }

  method foo                       # Invocant: '$self'
    { $self->bar }

  method foo (Foo $self: Bar $x)   # Parameter 'isa' classname
    { $self->use_bar($x) }

And there's more...

Perl6::Subs is a source filter that adds a very useful subset of Perl 6 subroutine syntax to Perl 5. Given a subroutine defined with a Perl 6 prototype, the code generated by Perl6::Subs will, at runtime, declare the formal parameters, assign them their values, and validate their contents according to both built-in and user-given rules.

Perl6::Subs supports all five categories of Perl 6 subroutine parameters, here listed in their mandatory order. (You may skip categories, but not reorder them.)

  • Method invocant, e.g. $self:). Invocant declarations are marked by a trailing colon rather than the usual comma. To declare an invocant when there are no other parameters, just end the prototype with the colon.
  • Mandatory positional, e.g. $foo.
  • Optional positional, e.g. "?$foo".
  • Optional named, e.g. "+$foo".
  • Required named, e.g. "+$foo is required".
  • Slurpy, e.g. *@rest or *%rest. Slurpy parameters must appear last, as they consume all remaining parameter values.

Perl 5's limited function call semantics (the single array @_) prevent Perl6::Subs from supporting all the features of Perl 6 parameter lists. A given subroutine can have either optional positional parameters or named parameters or a slurpy parameter; combining them is illegal. As the lone exception, a subroutine with named parameters may also have a slurpy hash; the hash will contain all the key/value pairs not explicitly given as named parameters.

Perl6::Subs understands the following type names, and will generate code that validates at runtime that a declared parameter's value actually has the given type, and throws an exception if it fails.

First, the fundamental Perl 6 types, which in Perl 6 will be unboxed (non-objects):

str:
Any defined scalar. (Note: References are permitted. Given Perl 5's overloading facility, a reference may actually have a useful string value if you go ahead and use it.) Due to the semantics of Perl 6's "str" type, use of "str" is recommended only for bare byte buffers without string semantics.
num:
A number; specifically a defined scalar that passes the test of "Scalar::Util::looks_like_number".
int:
An integer; specifically, a num with no fractional part.
ref:
Any reference value.
bool:
Any defined scalar.

Now, the "object types". Note that while Perl 6 considers all these to be objects, Perl 5 often doesn't. Also note that, in general, "undef" is permitted as a valid value for all object types.

Any:
Any value, including undef.
Str:
Any scalar value, including undef. (In Perl 5, this is a synonym for Any.)
Num:
A num, or undef.
Int:
An int, or undef.
Ref:
A reference value, or undef.
Array:
An array reference, or undef.
Hash:
A hash reference, or undef.
Code:
A code (subroutine) reference, or undef.
Rule:
A regexp reference (qr//), or undef.
IO:
A value that can be used for I/O: An IO handle reference (e.g. *STDOUT{IO}, a glob (e.g. *STDOUT), a glob reference (e.g. "\*STDOUT"), or undef. Note that autovivified file handles are legal "IO" values, as they are references to (blessed) globs.

Perl6::Subs also supports these type names which are not legal in Perl 6, but which may be useful in writing Perl 5:

Glob:
A glob value (e.g. *STDOUT), or undef.
GlobRef:
A glob reference (e.g. "\*STDOUT"), or undef.

Finally, any bareword other than the above used as a type name is assumed to name a user-defined class. A parameter so typed must satisfy UNIVERSAL::isa() of that class, or be undef. If Perl warnings are enabled at compile time, a mispelled class name will generate a diagnostic.

Perl6::Subs filters subroutines declared either with a Perl 6 style prototype; or with the "method" keyword replacing the word "sub" (in which case the "method" trait is implied). Perl6::Subs also understand both Perl 5 and Perl 6 syntax for subroutine traits (Perl 5 calls them "attributes"). Thus, these declarations are synonymous:

    sub foo is method {...}
    sub foo returns(Any) is method {...}
    sub foo ($self:) : method {...}
    method foo {...}
    method foo ($self:) {...}

However, this declaration uses no Perl 6 features, and therefore Perl6::Subs does not filter it:

    sub foo : method {...}

Perl6::Subs understands subroutine traits after the prototype declared with three syntax flavors:

  • Perl 6 standard trait syntax, e.g. "is trait" and "is trait(params)"
  • Perl 5 subroutine attributes, introduced with a colon, e.g. ":method"
  • As a special case, the Perl 6 trait "returns(TYPE)", which requires neither is nor a colon.

Perl6::Subs supports a subset of the Perl 6 type declaration syntax. Allowed parameter forms are "Type $var" and "$var of Type". Thus,

    sub foo (Int $i)

and

    sub foo ($i of Int)

are synonymous. Any parameter traits must be specified at the end of the given declaration. Thus a required named parameter of type Int may be specified as:

    sub foo (Int +$i is required)

or

    sub foo (+$i of Int is required)

(The only implemented parameter trait as of this writing is "is required", which is only meaningful on named parameters.)

You may create an anonymous subtype (restricted type) using a "where" clause, which specifies a block of code that must evaluate to true when $_ is set to a given value. For example, to accept only positive integers as parameters, you could write:

    sub foo (Int where { $_ > 0 } $i)

or

    sub foo ($i of Int where { $_ > 0 })

(The latter is clearer, in the author's opinion, since the variable is textually closer to the base type.)

If the environment variable "PERL6_SUBS_DEBUG" is set to a true value, Perl6::Subs will print to standard output the complete filtered text of any source file in which it is used.

If you're debugging Perl6::Subs itself, the environment variables "PERL6_SUBS_RD_TRACE" and "PERL6_SUBS_RD_HINTS" set the $::RD_TRACE and $::RD_HINTS variables, respectively, opening a window on the operation of "Parse::RecDescent".

Avoid variable named after Perl quoting operators.
Do not use parameter names that turn into Perl quoting operators when their sigils are stripped: "$y", "$m", "@tr", "@q", etc. If you do so, Filter::Simple will be fooled into thinking large parts of your program are quoted strings, and large parts of your code may go unfiltered.
Parameters are not aliased; "is copy" is the default.
In Perl 6, formal parameters are usually read-only aliases for the actual parameter values. Parameters with the "is rw" trait are writeable aliases, and parameters with the "is copy" trait are writeable copies.

Perl6::Subs defaults to "is copy" semantics for efficiency reasons. Given that we're working on top of Perl 5, this is unlikely to change. Read-only aliasing is not a Perl 5 feature; to provide its semantics would currently require tying, and that's just too slow for us to make it the default. On the other hand, support for "is rw" may someday be provided via Lexical::Alias.

No Perl 5 prototypes.
The Perl 5 code produced by this source filter never includes Perl 5 prototypes for the functions with Perl 6 prototypes. This is a design decision driven mostly by its intended usage: creating object-oriented Perl code. Method calls in Perl 5 always ignore prototypes. And if you don't know what a Perl5 prototype is, exactly, defining it can be a tricky thing.

I suspect that if we ever add this feature, it will be as an additional function attribute:

    sub foo (Int $x) is perl5_prototype($) { ... }
    

Some missing Perl 6 features that would be helpful in Perl 5 code:
  • Junction types (e.g. "Foo | Bar")
  • Default parameter values (e.g. "Int +$pos = 0")
  • Parameter traits and the features they enable (e.g. "Int +$pos is required". (Perl6::Subs doe parse parameter traits, but it then proceeds to ignore them.)
  • Perl 6 prototypes on sub declarations (as opposed to definitions).
  • Interspersed comments in sub definitions. If you include any comments from the "sub" keyword to the open brace of the sub body, bad things will happen. This bug should be easy to fix by using the "placeholder" regular expression provided so kindly by Damian.
  • The default invocant for methods is $self, because that's the convention used by about 90% of object-oriented code on CPAN. (The actual default invocant for Perl 6 is somewhat up in the air.)

    The default invocant for Perl6::Subs should probably be user-changable. But I'm not sure the best user interface. This would work:

      use Perl6::Subs invocant => '$this';
        

    And yet, would you really want to have to put that at the top of every module? You'd probably just start using $self. For a large project, something like this would be better:

      # MyProject.pm
      package MyProject;
      use Perl6::Subs::Defaults invocant => '$this';
        
  • There's a hook for support of Params::Validate: "valid {}", which works syntatically just like "where {}". As of this writing, it does nothing.

This module is a source filter. Source filters always break. For example, the breakage caused by parameter names that turn into Perl quoting operators when their sigils are stripped may never be fixed.

Please report any other bugs or feature requests to "bug-perl6-subs@rt.cpan.org", or through the web interface at <http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Perl6-Subs>. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

Chip Salzenberg, "<chip@pobox.com>"

Thanks to Heath Market Science <hmsonline.com> for funding creation of this module. Thanks also to Larry, Damian, Allison, et al for Perl 6 subroutine syntax, and to Damian for Filter::Simple and Parse::RecDescent.

Copyright 2005 Chip Salzenberg and Health Market Science.

This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

2005-04-13 perl v5.32.1

Search for    or go to Top of page |  Section 3 |  Main Index

Powered by GSP Visit the GSP FreeBSD Man Page Interface.
Output converted with ManDoc.