Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

use base { MODULE = version}? (a change to base.pm)

by crazyinsomniac (Prior)
on Mar 26, 2002 at 20:35 UTC ( [id://154507]=perlmeditation: print w/replies, xml ) Need Help??

update: the most recent version of this module is available at use base [ MODULE => version ]; (a change to base.pm).

i like to use base 'CGI::Application' quite often, but I also want at least CGI::Application::VERSION 2.1, and I dont like saying use CGI::Application 2.1, and since I don't wanna change the behaviour of base as it stands, I propose passing use base a {}, like
(readmore follows ~ code and most of the questions are after)

=head1 NAME base - Establish IS-A relationship with base class at compile time =head1 SYNOPSIS package Baz; use base qw(Foo Bar); ## new usage allowed by podmaster, allows for require MODULE versi +onnumber; package Baz; use base { Foo => 1, 'Foo::Bar' => 2}; ## need quotes use base \%{{ BARE::WORD => 2}}; ## only works like this =head1 DESCRIPTION Roughly similar in effect to BEGIN { require Foo; require Bar; push @ISA, qw(Foo Bar); } Will also initialize the %FIELDS hash if one of the base classes has it. Multiple inheritance of %FIELDS is not supported. The 'base' pragma will croak if multiple base classes have a %FIELDS hash. See L<fields> for a description of this feature. When strict 'vars' is in scope I<base> also let you assign to @ISA without having to declare @ISA with the 'vars' pragma first. If any of the base classes are not loaded yet, I<base> silently C<require>s them. Whether to C<require> a base class package is determined by the absence of a global $VERSION in the base package. If $VERSION is not detected even after loading it, <base> will define $VERSION in the base package, setting it to the string C<-1, set by base.pm>. The new feature of this module, allows for version checking via use base { 'MODULE' => 33 }; # version 33 which is roughly equivalent to use MODULE 33; use base 'MODULE'; and will C<croak> much like C<perl -MMODULE=33 -e 1> if version 33 of MODULE is not available =head1 HISTORY This module was introduced with Perl 5.004_04. =head1 SEE ALSO L<fields> =cut package base; use 5.006_001; our $VERSION = "1.02"; sub import { my $class = shift; my $fields_base; my $pkg = caller(0); my @bases = @_; ##podmaster - cause i don't wanna modify @bases my %BASV=(); ##podmaster if(ref $bases[0] eq 'HASH') { ##podmaster %BASV = %{$bases[0]}; @bases = keys %BASV; } foreach my $base (@bases) { ##podmaster next if $pkg->isa($base); push @{"$pkg\::ISA"}, $base; my $vglob; unless (${*{"$base\::VERSION"}{SCALAR}}) { eval "require $base"; # Only ignore "Can't locate" errors from our eval require. # Other fatal errors (syntax etc) must be reported. die if $@ && $@ !~ /^Can't locate .*? at \(eval /; unless (%{"$base\::"}) { require Carp; Carp::croak("Base class package \"$base\" is empty.\n", "\t(Perhaps you need to 'use' the module ", "which defines that package first.)"); } ${"$base\::VERSION"} = "-1, set by base.pm" unless ${*{"$base\::VERSION"}{SCALAR}}; } ##podmaster - allows for use base { module => versionnumber } if(%BASV and exists $BASV{$base} and $BASV{$base} > ${"${base}::VERSION"}) { ## wanted > av +ailable require Carp; Carp::croak("$base version $BASV{$base} required--this is only + version " .${"${base}::VERSION"}); } # A simple test like (defined %{"$base\::FIELDS"}) will # sometimes produce typo warnings because it would create # the hash if it was not present before. my $fglob; if ($fglob = ${"$base\::"}{"FIELDS"} and *$fglob{HASH}) { if ($fields_base) { require Carp; Carp::croak("Can't multiply inherit %FIELDS"); } else { $fields_base = $base; } } } if ($fields_base) { require fields; fields::inherit($pkg, $fields_base); } } 1;
Ideas comments suggestions are all welcome. I don't know if this has been brought up before (looked, didn't find much), and I wasn't able to check if the latest base.pm does this, and mine don't (5.6) , so ... feedback!

btw, why doesn't the power of => kick in "use base { FOO::BAR => 1 };"?

P.S ~ could I get into core $^O? ;)

update ( Mon Jun 10 07:19:10 2002 ): *sigh* it appears the problem usage was with an unless statement that I had changed to if, but somehow reverted to unless again. It's been fixed now, and I sent this thing to perl5-porters (in preparation for which, i rewrote it, along with a test).

#!/usr/bin/perl -w package GENERIC; use lib qw(.); use strict; BEGIN { use base 'CGI::Application'; # regular usage use base { 'CGI::Application' => 2.1 }; # new usage use base { # do the switch'a'roo to see an err message 'DBI' => 1, # 'DBI' => 16, }; } sub setup { my $self = shift; $self->start_mode('hi'); $self->mode_param('op'); $self->run_modes( hi => sub {" hi ".join(' ',caller())}, AUTOLOAD => sub {" hello ".join(' ',caller())}, ); } package main; my $DE_GENERIC = GENERIC->new(); $DE_GENERIC->run();

 
______crazyinsomniac_____________________________
Of all the things I've lost, I miss my mind the most.
perl -e "$q=$_;map({chr unpack qq;H*;,$_}split(q;;,q*H*));print;$q/$q;"

Replies are listed 'Best First'.
The power of =
by RMGir (Prior) on Mar 26, 2002 at 22:17 UTC
    You asked:

    btw, why doesn't the power of => kick in "use base { FOO::BAR => 1 };"?

    I _think_ that's because the => only quotes the immediately preceding bareword. So you're probably running into the same issue you'd have if you tried to do

    use base { HYPHENATED-MODULE => 2.1 };
    But that's all just guessing.
    --
    Mike

      I believe that it is simply a bug. I recall discussing this before but can't find a node on it. I think it is fixed in 5.6.1, but I don't have that handy either.

              - tye (but my friends call me "Tye")
        I don't know if it is bug or feature :) but indeed Foo::Bar => 1 syntax seems to work in 5.6.1 but not in 5.005 (I haven't checked it on other versions).

        --
        Ilya Martynov (http://martynov.org/)

use base [ MODULE => version ]; (a change to base.pm)
by crazyinsomniac (Prior) on Jun 17, 2002 at 10:46 UTC
    After I finally decided to submit this to the perl5 porters, somebody took interest and pointed out a few flaws, like the fact that the original version of my update breaks inheritance. Benjamin Goldberg also went out to say that he likes to use the VERSION function for version checking, so here it is, the final rendition of base.pm (replacing the {} with [ ], and not breaking inheritance, or causing weirdo exporter errors)
    a patch for CORE MODULE base.pm, to allow for use base [ MODULE => VER +SION ]; Feel free to do as you wish. A thanks to benjamin goldbert for taking the time to point out the fla +ws in my previous submission. =head1 NAME base - Establish IS-A relationship with base class at compile time =head1 SYNOPSIS package Baz; use base qw(Foo Bar); ## new usage allowed by podmaster, allows you to request a version + number; package Baz; use base [ Foo => 1, 'Foo::Bar' => 2 ]; =head1 DESCRIPTION Roughly similar in effect to BEGIN { require Foo; require Bar; push @ISA, qw(Foo Bar); } Will also initialize the %FIELDS hash if one of the base classes has it. Multiple inheritance of %FIELDS is not supported. The 'base' pragma will croak if multiple base classes have a %FIELDS hash. See L<fields> for a description of this feature. When strict 'vars' is in scope I<base> also let you assign to @ISA without having to declare @ISA with the 'vars' pragma first. If any of the base classes are not loaded yet, I<base> silently C<require>s them. Whether to C<require> a base class package is determined by the absence of a global $VERSION in the base package. If $VERSION is not detected even after loading it, <base> will define $VERSION in the base package, setting it to the string C<-1, set by base.pm>. The new feature of this module, allows for version checking via use base [ 'MODULE' => 33 ]; # version 33 which is roughly equivalent to use MODULE 33; use base 'MODULE'; and will C<croak> much like C<perl -MMODULE=33 -e 1> if version 33 of MODULE is not available =head1 HISTORY This module was introduced with Perl 5.004_04. =head1 SEE ALSO L<fields> =cut package base; use 5.006_001; our $VERSION = "1.02"; sub import { my $class = shift; my $fields_base; my $pkg = caller(0); my @bases = @_; ##podmaster - cause i don't wanna modify @bases my %BASV=(); ##podmaster my @BASV=(); ##podmaster if(ref $bases[0] eq 'ARRAY') { ##podmaster my $beep = 0; @BASV = @{$bases[0]}; %BASV = @BASV; @bases = grep {$_} map { ($beep++ % 2) ? () : ($_) } @BASV; } foreach my $base (@bases) { ##podmaster next if $pkg->isa($base); push @{"$pkg\::ISA"}, $base; my $vglob; unless (${*{"$base\::VERSION"}{SCALAR}}) { eval "require $base"; # Only ignore "Can't locate" errors from our eval require. # Other fatal errors (syntax etc) must be reported. die if $@ && $@ !~ /^Can't locate .*? at \(eval /; unless (%{"$base\::"}) { require Carp; Carp::croak("Base class package \"$base\" is empty.\n", "\t(Perhaps you need to 'use' the module ", "which defines that package first.)"); } ${"$base\::VERSION"} = "-1, set by base.pm" unless ${*{"$base\::VERSION"}{SCALAR}}; #' } ##podmaster - allows for use base [ module => versionnumber ] ## thanks Benjamin Goldberg if(exists $BASV{$base} ) { ## wanted > available $base->VERSION( $BASV{$base} ); } # A simple test like (defined %{"$base\::FIELDS"}) will # sometimes produce typo warnings because it would create # the hash if it was not present before. my $fglob; if ($fglob = ${"$base\::"}{"FIELDS"} and *$fglob{HASH}) { if ($fields_base) { require Carp; Carp::croak("Can't multiply inherit %FIELDS"); } else { $fields_base = $base; } } } if ($fields_base) { require fields; fields::inherit($pkg, $fields_base); } } 1;

     
    ______crazyinsomniac_____________________________
    Of all the things I've lost, I miss my mind the most.
    perl -e "$q=$_;map({chr unpack qq;H*;,$_}split(q;;,q*H*));print;$q/$q;"

Re: use base { MODULE = version}? (a change to base.pm)
by Anonymous Monk on Mar 27, 2002 at 03:54 UTC
    I used your base module, and it worked fine for a while, but then I started getting weirdo Exporter errors (after using HTML::Template), can anyone scrutinize this code? Thank you.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://154507]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (2)
As of 2024-04-26 07:49 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found