#!/usr/local/bin/perl5
# perl5 -x notes 2> expected > actual ; diff expected actual
open(EVAL, "| perl5 -x") || die "Can't pipe to perl5\n";
while (<DATA>) {
m/prints ``(.*)''$/ && print STDERR $1,"\n";
print EVAL $_;
}
__END__
#!/usr/local/bin/perl5
#
# Perl5a6 notes: Patchlevel 3
#
# This document is in the public domain.
#
# Written by Tony Sanders <
[email protected]>
#
# Quick examples of the new Perl5 features as of alpha6. Look in the
# file Changes, the man page, and in the test suite (esp t/op/ref.t)
# for more information. There are also a number of files in the alpha6
# release (e.g., tie*) that show how to use various features. Also, there
# are a number of package modules in lib/*.pm that are of interest.
#
# Thanks to the following for their input:
#
[email protected]
# Daniel Faken <
[email protected]>
# Tom Christiansen <
[email protected]>
# Dean Roehrich <
[email protected]>
# Larry Wall <
[email protected]>
# Lionel Cons <
[email protected]>
#
# BEGIN { }
# executed at load time
print "doody\n";
BEGIN { print "howdy\n"; } # prints ``howdy''
# then prints ``doody''
# END { }
# executed at exit time in reverse order of definition
END { print "blue sky\n"; } # will print ``blue sky''
END { print "goodbye\n"; } # will print ``goodbye''
# (expr?lval:lval) = value;
# The (?:) operator can be used as an lvalue.
$a = 1; $b = 2;
(defined $b ? $a : $b) = 10;
print "$a:$b\n"; # prints ``10:2''
# new functions: abs, chr, uc, ucfirst, lc, lcfirst
print abs(-10), "\n"; # prints ``10''
print chr(64), "\n"; # prints ``@''
print uc("the"), "\n"; # prints ``THE''
print ucfirst("the"), "\n"; # prints ``The''
print lc("THE"), "\n"; # prints ``the''
print lcfirst("THE"), "\n"; # prints ``tHE''
# references
# references
$thing1 = "testing";
$ref = \$thing1; # \ creates a reference
print $$ref,"\n" if ${$ref} eq $$ref; # deref, prints ``testing''
# symbolic references
sub bat { "baz"; }
sub baz { print "foobar\n" };
&{&bat}; # prints ``foobar''
# symbol table assignment: *foo = \&func;
# replaces an item in the symbol table (function, scalar, array, hash)
# *foo = \$bar replaces the scalar
# *foo = \%bar replaces the hash table
# *foo = \@bar replaces the array
# *foo = \&bar replaces the function
# *foo = *bar all of the above (including FILEHANDLE!)
# XXX: can't do just filehandles (yet)
#
# This can be used to import and rename a symbol from another package:
# *myfunc = \&otherpack::otherfunc;
# AUTOLOAD { ...; }
# called if method not found, passed function name in $AUTOLOAD
# @_ are the arguments to the function.
# goto &func;
# goto's a function, used by AUTOLOAD to jump to the function
# qw/arg list/; qw(arg list);
# quoted words, yields a list; works like split(' ', 'arg list')
# not a function, more like q//;
{
package AutoLoader;
AUTOLOAD {
eval "sub $AUTOLOAD" . '{ print "@_\n"}';
goto &$AUTOLOAD }
package JAPH;
@ISA = (AutoLoader);
sub foo2 { &bar }
foo2 qw(Just another Perl hacker,);
# prints ``Just another Perl hacker,''
}
# Larry notes:
# You might point out that there's a canned Autoloader base class in the
# library. Another subtlety is that $AUTOLOAD is always in the same
# package as the AUTOLOAD routine, so if you call another package's
# AUTOLOAD explicitly you have to set $AUTOLOAD in that package first.
# my
# lexical scoping
sub samp1 { print $z,"\n" }
sub samp2 { my($z) = "world"; &samp1 }
$z = "hello";
&samp2; # prints ``hello''
# package;
# empty package; for catching non-local variable references
sub samp3 {
my $x = shift; # local() would work also
package; # empty package
$main::count += $x; # this is ok.
# $y = 1; # would be a compile time error
}
# =>
# works like comma (,); use for key/value pairs
# sometimes used to disambiguate the final expression in a block
# might someday supply warnings if you get out of sync
%foo = ( abc => foo );
print $foo{abc},"\n"; # prints ``foo''
# ::
# works like tick (') (use of ' is deprecated in perl5)
print $main::foo{abc},"\n"; # prints ``foo''
# bless ref;
# Bless takes a reference and returns an "object"
$oref = bless \$scalar;
# ->
# dereferences an "object"
$x = { def => bar }; # $x is ref to anonymous hash
print $x->{def},"\n"; # prints ``bar''
# method derefs must be bless'ed
{
# initial cap is encouraged to avoid naming conflicts
package Sample;
sub samp4 { my($this) = shift; print $this->{def},"\n"; }
sub samp5 { print "samp5: ", $_[1], "\n"; }
$main::y = bless $main::x; # $x is ref, $y is "object"
}
$y->samp4(); # prints ``bar''
# indirect object calls (same as $y->samp5(arglist))
samp5 $y arglist; # prints ``samp5: arglist''
# static method calls (often used for constructors, see below)
samp5 Sample arglist; # prints ``samp5: arglist''
# function calls without &
sub samp6 { print "look ma\n"; }
samp6; # prints ``look ma''
# "forward" decl
sub samp7;
samp7; # prints ``look pa''
sub samp7 { print "look pa\n"; }
# no decl requires ()'s or initial &
&samp8; # prints ``look da''
samp8(); # prints ``look da''
sub samp8 { print "look da\n"; }
# ref
# returns "object" type
{
package OBJ1;
$x = bless \$y; # returns "object" $x in "class" OBJ1
print ref $x,"\n"; # prints ``OBJ1''
}
# and non-references return undef.
$z = 1;
print "non-ref\n" unless ref $z; # prints ``non-ref''
# ref's to "builtins" return type
print ref \$ascalar,"\n"; # prints ``SCALAR''
print ref \@array,"\n"; # prints ``ARRAY''
print ref \%hash,"\n"; # prints ``HASH''
sub func { print shift,"\n"; }
print ref \&func,"\n"; # prints ``CODE''
print ref \\$scalar,"\n"; # prints ``REF''
# tie
# bind a variable to a package with magic functions:
# new, DESTROY, fetch, store, delete, firstkey, nextkey
# The exact function list varies with the variable type,
# see the man page and tie* for more details.
# Usage: tie variable, PackageName, ARGLIST
{
package TIEPACK;
sub new { print "NEW: @_\n"; local($x) = $_[1]; bless \$x }
sub fetch { print "fetch ", ref $_[0], "\n"; ${$_[0]} }
sub store { print "store $_[1]\n"; ${$_[0]} = $_[1] }
DESTROY { print "DESTROY ", ref $_[0], "\n" }
}
tie $h, TIEPACK, "black_tie"; # prints ``NEW: TIEPACK black_tie''
print $h, "\n"; # prints ``fetch TIEPACK''
# prints ``black_tie''
$h = 'bar'; # prints ``store bar''
untie $h; # prints ``DESTROY SCALAR''
# References
$sref = \$scalar; # $$sref is scalar
$aref = \@array; # @$aref is array
$href = \%hash; # %$href is hash table
$fref = \&func; # &$fref is function
$refref = \$fref; # ref to ref to function
&$$refref("call the function"); # prints ``call the function''
# Anonymous data-structures
%hash = ( abc => foo ); # hash in perl4 (works in perl5 also)
print $hash{abc},"\n"; # prints ``foo''
$ref = { abc => bar }; # reference to anon hash
print $ref->{abc},"\n"; # prints ``bar''
@ary = ( 0, 1, 2 ); # array in perl4 (works in perl5 also)
print $ary[1],"\n"; # prints ``1''
$ref = [ 3, 4, 5 ]; # reference to anon array
print $ref->[1],"\n"; # prints ``4''
# Nested data-structures
@foo = ( 0, { name => foobar }, 2, 3 ); # $#foo == 3
$aref = [ 0, { name => foobar }, 2, 3 ]; # ref to anon array
$href = { # ref to hash of arrays
John => [ Mary, Pat, Blanch ],
Paul => [ Sally, Jill, Jane ],
Mark => [ Ann, Bob, Dawn ],
};
print $href->{Paul}->[0], "\n"; # prints ``Sally''
print $href->{Paul}[0],"\n"; # shorthand version, prints ``Sally''
print @{$href->{Mark}},"\n"; # prints ``AnnBobDawn''
# @ISA
# Multiple Inheritance (get rich quick)
{
package OBJ2; sub abc { print "abc\n"; }
package OBJ3; sub def { print "def\n"; }
package OBJ4; @ISA = ("OBJ2", "OBJ3");
$x = bless { foo => bar };
$x->abc; # prints ``abc''
$x->def; # prints ``def''
}
# Packages, Classes, Objects, Methods, Constructors, Destructors, etc.
# XXX: need more explinations and samples
{
package OBJ5;
sub new { print "NEW: @_\n"; my($x) = "empty"; bless \$x }
sub output { my($this) = shift; print "value = $$this\n"; }
DESTROY { print "OBJ5 DESTROY\n" }
}
# Constructors are often written as static method calls:
$x = new OBJ5; # prints ``NEW: OBJ5''
$x->output; # prints ``value = empty''
# The destructor is responsible for calling any base class destructors.
undef $x; # prints ``OBJ5 DESTROY''
# require Package;
# same as: BEGIN { require 'Package.pm'; }
# require <float>;
# checks against the perl version number
require 5.000; # requires perl 5.0 or better
# Package Modules
# ===============
# Yes, these are all very sketchy. See the .pm file for details.
# DynamicLoader (builtin)
# Public: &bootstrap
# Load a shared library package on systems that support it
# This incomplete example was extracted from lib/POSIX.pm
#
# package POSIX;
# requires Exporter; require AutoLoader;
# @ISA = (Exporter, AutoLoader, DynamicLoader);
# @EXPORT = qw(closedir, opendir, [..., lots of functions]);
# bootstrap POSIX;
# Larry notes:
# The gist of it is that DynamicLoader::bootstrap is only called if main.c
# didn't already define MYPACKAGE::bootstrap. So the .pm file doesn't know
# (or care) whether the module is statically or dynamically loaded.
# AutoLoader.pm
# Public: &AUTOLOAD
# Causes functions from .../lib/perl/auto/PACKAGE/*.al to autoload
# when used but not defined.
# Config.pm
# Exports: %Config
# The data from the Configure script for perl programs (yeah)
# English.pm
# Exports: (lots of verbose variables)
# The "english" versions of things like $_ $| $=
# Exporter.pm
# Public: &import
# import PACKAGE [@symbols]
# requires PACKAGE to define @EXPORT
{
package FOOBAR;
require Exporter;
@ISA = (Exporter);
@EXPORT = (foo, bar);
sub foo { print "FOO\n" };
sub bar { print "BAR\n" };
1;
package BAT;
# require FOOBAR; # not in this example
import FOOBAR;
@ISA = ();
&foo; # prints ``FOO''
}
# FileHandle.pm
# Exports: (lots of filehandle functions)
# English versions of various filehandle operations
# Hostname.pm
# Exports: &hostname
# Routine to get hostname
# {
# require Hostname; import Hostname;
# print &hostname,"\n"; # prints your hostname
# }
# POSIX.pm
# Exports: (posix functions and defines)
# POSIX.1 bindings
# SDBM_File.pm
# SDBM interfaces (use with `tie')
# Other DBM interfaces work the same way
# when the script exits the END section gets executed and prints ``goodbye''
# ENDs are executed in reverse order of definition. prints ``blue sky''
__END__