develooper Front page | perl.perl5.porters | Postings from May 2003

selective base.pm import

Thread Next
From:
Jim Cromie
Date:
May 31, 2003 07:52
Subject:
selective base.pm import
Message ID:
3ED8DD64.5060607@divsol.com

in msg:   
http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2003-04/msg00294.html

Graham left open the possibility that selective import was not verboten.
The following example and patch shows it just might be useful.

In this change, base.pm treats args which are ARRAY-refs as an import 
list, which is flattened
before calling import.  Similar treatment for other REFs is possible, 
but unimplemented ...

The example and patch is purposely rough, I dont presume it will get 
applied without
the requisite kicking-around.

Here it is, in action

[jimc@harpo base]$ ~/bleadperl/perl -I ~/bleadperl/lib ex.pl
A importing into A, w mode 1
myB importing into myB, w mode 2
A importing into AB, w
called A::foo (AB=HASH(0x81304a0))
A's my $mode == 1
1called myB::bar (AB=HASH(0x81304a0))
myB's my $mode == 2
1[jimc@harpo base]$

I havent looked into why A and B import themselves, I still have to 
apply the belt-sander.

It could have interesting effects, esp with old-school stunts like 
exposing parent-package hashes
(since theyre often done inside qw(), theyre not formally interfering, 
but are close enough for
potential confusion)

anyway, enjoy,
jimc


[jimc@harpo base]$ more A* myB* ex.pl base.diff
::::::::::::::
AB.pm
::::::::::::::

package AB;
use base ( A => [ mode => 1],
       myB => [ mode => 2] );

sub new {
    bless {}, shift;
}

1;
::::::::::::::
A.pm
::::::::::::::

package A;
my $mode;

sub import {
    my ($cpkg, @rest) = @_;
    print "A importing into $cpkg, w @rest\n";
    if ($rest[0] eq mode) {
    $mode = $rest[1];
    }
}

sub foo {
    print "called A::foo (@_)\n";
    print "A's my \$mode == $mode\n" if $mode;
}

1;
::::::::::::::
myB.pm
::::::::::::::

package myB;
my $mode = 0;

sub import {
    my ($cpkg, @rest) = @_;
    print "myB importing into $cpkg, w @rest\n";
    if ($rest[0] eq mode) {
    $mode = $rest[1];
    }
}

sub bar {
    print "called myB::bar (@_)\n";
    print "myB's my \$mode == $mode\n" if $mode;
}

1;
::::::::::::::
ex.pl
::::::::::::::

use AB;

$obj = new AB;
print $obj->foo;
print $obj->bar;
::::::::::::::
base.diff
::::::::::::::
--- base.pm    Fri May 30 14:16:52 2003
+++ base.pm.new    Fri May 30 14:16:52 2003
@@ -52,7 +52,9 @@
     my $fields_base;
     my $pkg = caller(0);
 
-    foreach my $base (@_) {
+    my @baselist = @_;
+
+    while (my $base = shift @baselist) {
     next if $pkg->isa($base);
         my $vglob;
     if ($vglob = ${"$base\::"}{VERSION} and *$vglob{SCALAR}) {
@@ -84,11 +86,30 @@
         $fields_base = $base;
         }
     }
+        if (ref $baselist[0] eq 'ARRAY') {
+        $base->import(@{shift @baselist});
+    }
     }
     if ($fields_base) {
     require fields;
     fields::inherit($pkg, $fields_base);
     }
+    @_ = @baselist;
 }
 
 1;
+
+__END__
+
+=head1 Import extension
+
+If an item following a base-class is an array-ref, its contents are
+taken to be symbols that should be imported into the user class.  This
+should be non-interfering with current import-less operation; package
+names are barewords, strings or pre-initialized scalars, and are thus
+(by definition) not array-refs.
+
+    # a stretched example
+    package NewGrass;
+    use base ( BlueGrass => [qw/ banjo /],
+           Jazz      => [qw/ trumpet /] );
[jimc@harpo base]$        


Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About