Front page | perl.perl6.language |
Postings from December 2001
Perl 6's Exporter
Thread Next
From:
Brent Dax
Date:
December 21, 2001 23:21
Subject:
Perl 6's Exporter
Message ID:
FJELLKOPEAGHOOODKEDPCENNCOAA.brentdax@cpan.org
I've been thinking about improvements that could be made to Exporter for
Perl 6.
1. Choosing where to export to:
use Data::Dumper 'Dumper' => 'dumpvar';
#exports Data::Dumper::Dumper to Main::dumpvar (or whatever)
2. Built-in switch handling:
use Data::Dumper ('Dumper' : qw(+Indent=2 +Useqq));
#imports Dumper, sets $Data::Dumper::Indent=2, and
# does $Data::Dumper::Useqq is true
3. Warnings about conflicts:
use warnings 'Exporter';
sub Dumper { ... }
use Data::Dumper qw(Dumper);
#prints out a warning (not just 'redefined subroutine', either).
4. For modules, saying 'use Exporter' should be enough to get import.
If you don't want Exporter's import(), just C<use Exporter()>.
5. In addition to @EXPORT/@EXPORT_OK/%EXPORT_TAGS, provide a way to do
it on the 'use Exporter' line.
So, with those requirements and what knowledge of Perl 6 I have, I
present a preliminary Exporter. I typed it directly into the mailer, so
there's a good chance of mistakes. If anyone spots any mistakes in it,
let me know.
module Exporter;
use strict;
use warnings;
use warnings::register; #assuming this continues to exist...
sub myimport($exp_from : *@symbols=() : *@options=()) {
my $exp_to=caller.package; #is this how caller is used?
pkg_alias($exp_from, "Exporter::From");
pkg_alias($exp_to, "Exporter::To");
#defaults
@symbols //= @Exporter::From::EXPORT;
#expand tags to their values
@symbols=map {
/^:/ ??
@{%Exporter::From::EXPORT_TAGS}{$_}} ::
$_
} @symbols;
for(@symbols) {
#handle version numbers
if(/^[\d.]+$/) {
$exp_from.require_version($_);
next;
}
#handle renamed exports
my($to, $from)=$_.ref eq 'PAIR' ? ($_.left, $_.right) : ($_, $_);
for($to, $from) {
#make sure it has some sort of sigil
$_='&' _ $_ unless m'^[$@%&]';
}
warnings::warnif("$from exported from $exp_from conflicts with
existing $to at $(caller.file) line $(caller.line).\n")
if defined %Exporter::To::{$to};
die("$exp_from doesn't export $from at $(caller.file) line
$(caller.line).\n")
unless grep {/^$from$/} @Exporter::From::EXPORT,
@Exporter::From::EXPORT_OK;
%Exporter::To::{$to}=%Exporter::From::{$from};
}
for(@options) {
my($sign, $name, $value)=/[+-]([[\w]&&[^\d]]\w+)(?:=(.*))?/s;
my $targ := ${$Exporter::From::{$name}};
given($sign) {
when('+'): {
if(defined $value) {
$targ=$value;
}
else {
$targ is true;
}
}
when('-') {
if($targ.props{true}) {
$targ is false;
}
else {
undef $targ;
}
}
}
}
}
sub import($pkg : ARRAY $export=undef, ARRAY $ok=undef, HASH
$tags=undef) {
my $from_pkg=caller.package;
pkg_alias($from_pkg, "Exporter::From");
&Exporter::From::import := &myimport;
#another way to decide what to export:
#use Exporter(
# export => [qw(foo bar)],
# ok => [qw(baz quux],
# tags => { :argc => ['argv'] }
#);
if(defined $export) {
@Exporter::From::EXPORT=@$export;
}
if(defined $ok) {
@Exporter::From::EXPORT_OK=@$ok;
}
if(defined $tags) {
%Exporter::From::EXPORT_TAGS=%$tags;
}
}
sub pkg_alias($original, $new) {
#Any sufficiently encapsulated hack...
no strict 'refs';
%{"${original}::"} := %{"${new}::"}; #XXX will this actually work?
}
=head1 NAME
Exporter - Implements default import method for modules
=head1 SYNOPSIS
In MyModule.pm:
module MyModule;
use Exporter(
export => [qw(foo @bar)],
ok => [qw($baz quux)],
tags => { :argc => ['@argv %argv']}
);
In other files:
use MyModule; #imports everything in export
use MyModule 'quux'; #imports only &quux
use MyModule ':argc' #imports @argv and %argv
use MyModule(); #imports nothing at all
=head1 DESCRIPTION
TODO: Fill this in.
=head1 BUGS
Who knows--this code is for a language that hasn't been fully defined
and which doesn't yet have an implementation.
=head1 AUTHOR
The Perl 6 core developers. (Preliminary version by Brent Dax.)
=cut
--Brent Dax
brentdax@cpan.org
Configure pumpking for Perl 6
"Nothing important happened today."
--George III of England's diary entry for 4-Jul-1776
Thread Next
-
Perl 6's Exporter
by Brent Dax