cvsuser 01/11/29 15:46:38
Added: P5EEx/Beige/P5EEx/Beige ClassImplementor.pm ModuleTest.pm
ModuleTestDemo.pl
Log:
I'm a bit happier with this package. a much better building block. still lots to do
though.
Revision Changes Path
1.1 p5ee/P5EEx/Beige/P5EEx/Beige/ClassImplementor.pm
Index: ClassImplementor.pm
===================================================================
#!/usr/local/perl/bin
#
# Inline : methods declared in line with perl code.
# the class calling this code forms the object
# called.
#
# Dynamic : methods can be linked to at the run time.
# the class calling this class forms the
#
# Template : Similar in development style to Dynamic
# This defines methods that can be used
# as a child class
#
# Implementor : An implementor of a dynamic
# This specifies the code that is to be used
# the dynamic and implementor are linked on a first
# come first served basis
#
# Derived : This conforms to a given template. The class
# which is derived is called as a class in it's
# own right.
#
use strict;
package ClassImplementor;
{
my %classdata = (
ClassStore => {},
);
sub import
{
my $class = shift;
my %args = (
Mode => undef, # Can be
INLINE or DYNAMIC or IMPLEMENTOR or template
Target => undef, # The name of the
package that this implements
@_
);
# clean up namespace pollution from last import
my $pack = caller; # get calling package
die "Cannot Call from main\n" if ( $pack eq "main" || ! $pack );
die "Class Already Defined\n" if ( defined
${$classdata{ClassStore}}{$pack} );
# print $pack."\n";
# print @_;
$classdata{Scope} = $pack;
$classdata{Mode} = $args{Mode};
$classdata{Group} = $args{Group};
$classdata{MethodContext} = {};
for ( $args{Mode} )
{
/Inline/ && do {
no strict 'refs';
*{
join"::",($pack,"DeclareMethod") } = \&_DeclareMethodInline;
*{ join"::",($pack,"Object") }
= \&_Object;
*{ join"::",($pack,"Class") }
= \&_Class;
*{
join"::",($pack,"Subroutene") } = \&_Subroutene;
*{ join"::",($pack,"Object") }
= \&_Object;
*{ join"::",($pack,"Groups") }
= \&_Groups;
*{
join"::",($pack,"Arguments") } = \&_Arguments;
*{ join"::",($pack,"Rules") }
= \&_Rules;
*{ join"::",($pack,"Defaults")
} = \&_Defaults;
*{ join"::",($pack,"With") } =
\&_With;
${$classdata{ClassStore}}{$pack} = _ClassTemplate($pack);
last;
};
/Dynamic/ && do {
*{
join"::",($pack,"DeclareMethod") } = \&_DeclareMethodDynamic;
*{ join"::",($pack,"Object") }
= \&_Object;
*{ join"::",($pack,"Class") }
= \&_Class;
*{
join"::",($pack,"Subroutene") } = \&_Subroutene;
*{ join"::",($pack,"Object") }
= \&_Object;
*{ join"::",($pack,"Groups") }
= \&_Groups;
*{ join"::",($pack,"Rules") }
= \&_Rules;
*{
join"::",($pack,"Arguments") } = \&_Arguments;
*{ join"::",($pack,"Defaults")
} = \&_Defaults;
${$classdata{ClassStore}}{$pack} = _ClassTemplate($pack);
last;
};
/Implementor/ && do {
*{
join"::",($pack,"DeclareMethod") } = \&_DeclareMethodImplementor;
*{ join"::",($pack,"With") } =
\&_With;
last;
};
/Template/ && do {
*{
join"::",($pack,"DeclareMethod") } = \&_DeclareMethodTemplate;
*{ join"::",($pack,"Object") }
= \&_Object;
*{ join"::",($pack,"Class") }
= \&_Class;
*{
join"::",($pack,"Subroutene") } = \&_Subroutene;
*{ join"::",($pack,"Object") }
= \&_Object;
*{ join"::",($pack,"Groups") }
= \&_Groups;
*{ join"::",($pack,"Rules") }
= \&_Rules;
*{
join"::",($pack,"Arguments") } = \&_Arguments;
*{ join"::",($pack,"Defaults")
} = \&_Defaults;
${$classdata{ClassStore}}{$pack} = _ClassTemplate($pack);
last;
};
/Derived/ && do {
*{
join"::",($pack,"DeclareMethod") } = \&_DeclareMethodDerived;
*{ join"::",($pack,"With") } =
\&_With;
last;
};
die "Not Recognised\n";
};
};
sub _ClassTemplate # defines a class for a template
{
return {
Type => shift,
Methods => undef,
};
}
sub _DeclareMethodInline # declares a method declaration for inline
code
{
my $name = shift;
my $ptr = $classdata{MethodContext};
my $pack = caller;
die "Attempt to define module outside of scope\n" unless (
$classdata{Scope} eq $pack );
die "Attempt to redefine Method\n" if ( exists
${${$classdata{MethodContext}}{Methods}}{$name} );
die "Accessor Not Defined\n" unless ( defined $ptr -> {Caller} );
# define Accessor test
my $acctest;
for ( $ptr -> {Caller} )
{
my $m = ' my ($m,%a) = @_;';
/^Object$/ && do {
$acctest = $m;
$acctest .= 'die "Must
be called by object\n" unless ( ref $m eq "'.$pack.'" );';
last;
};
/^Class$/ && do {
$acctest = $m;
$acctest .= 'die "Must
be called by class\n" unless ( $m eq "'.$pack.'" );';
last;
};
/^Sunroutene$/ && do {
$acctest = 'my $m;my
(%a) = @_;';
last;
};
/^Method$/ && do {
$acctest = $m;
$acctest .= 'die "Must
be called as method\n" unless ( $m eq "'.$pack.'" | ref $m eq "'.$pack.'" );';
last;
};
die "Bad accessor";
};
# Ensure defaults, if defined are present in arguments
if ( ref $ptr -> {Defaults} eq "HASH" )
{
while ( my ($k,$v) = each %{ $ptr -> {Defaults} } )
{
die "Default defined for invalid argument\n" unless (
exists ${ $ptr -> {Arguments} }{$k} );
${ $ptr -> {Arguments} }{ $k } = $v;
};
};
# Ensure rules, if defined are in present in arguments
if ( ref $ptr -> {Rules} eq "HASH" )
{
while ( my ($k,$v) = each %{ $ptr -> {Rules} } )
{
die "Rule defined for invalid argument\n" unless (
exists ${ $ptr -> {Arguments} }{$k} );
};
};
# Argument Test
my $argtest;
if ( ref $ptr -> {Arguments} eq "HASH" && keys %{ $ptr -> {Arguments}
} )
{
# copy in defaults
$argtest = '%a = (('.(join ",",map { "'".$_."'" } ( %{$ptr ->
{Arguments}} )).'),%a);';
# Ensure correct number of arguments passed
$argtest .= 'die "Bad Arguments\n" unless ( scalar keys (%a)
== '.scalar keys (%{ $ptr -> {Arguments} }).' );';
# check against rules
# and recreate @_
$argtest .= '@_ = ( defined $m ? ($m,(%a) ) : (%a) );';
}
else
{
$argtest = 'die "Arguments Not permitted\n" if ( scalar keys
%a );';
}
${${$classdata{MethodContext}}{Methods}}{$name} = $ptr;
{
my $sub = eval
'sub { '.
$acctest.
$argtest.
'goto
${${$classdata{MethodContext}}{Methods}}{'.$name.'}->{Code} };';
if ( $@ )
{
die "Cannot Create Linking subroutene\n";
}
no strict 'refs';
*{ join "::",($classdata{Scope}, $name) } = $sub;
}
};
sub _DeclareMethodDynamic; # declares a method declaration for
dynamic code
{
};
sub _DeclareMethodImplementor; # declares a method declaration for inline
code
{
};
sub _DeclareMethodTemplate; # declares a method declaration for inline
code
{
};
sub _DeclareMethodDerived; # declares a method declaration for inline
code
{
};
sub _Object() # Returns "Object" for nice syntax
{
my $pack = caller; # get calling package
die "Attempt to define module outside of scope\n" unless (
$classdata{Scope} eq $pack );
my $ptr = $classdata{MethodContext};
$ptr -> {Caller} = "Object";
};
sub _Class() # Returns "Class" for nice syntax
{
my $pack = caller; # get calling package
die "Attempt to define module outside of scope\n" unless (
$classdata{Scope} eq $pack );
my $ptr = $classdata{MethodContext};
$ptr -> {Caller} = "Class";
};
sub _Subroutene() # Returns "Subroutene" for nice syntax
{
my $pack = caller; # get calling package
die "Attempt to define module outside of scope\n" unless (
$classdata{Scope} eq $pack );
my $ptr = $classdata{MethodContext};
$ptr -> {Caller} = "Class";
};
sub _Method() # Returns "Method" for nice syntax
{
my $pack = caller; # get calling package
die "Attempt to define module outside of scope\n" unless (
$classdata{Scope} eq $pack );
my $ptr = $classdata{MethodContext};
$ptr -> {Caller} = "Method";
};
sub _Arguments(@) # Takes in a list, returns a hash ref
{
my $pack = caller; # get calling package
die "Attempt to define module outside of scope\n" unless (
$classdata{Scope} eq $pack );
my $ptr = $classdata{MethodContext};
$ptr -> {Arguments} = {};
map { $ptr -> {Arguments} -> { $_ } = undef } @_;
};
sub _Rules (@)
{
my $pack = caller; # get calling package
die "Attempt to define module outside of scope\n" unless (
$classdata{Scope} eq $pack );
my $ptr = $classdata{MethodContext};
$ptr -> {Rules} = {@_};
}
sub _Defaults(@) # Takes in a list, returns a hash ref
{
my $pack = caller; # get calling package
die "Attempt to define module outside of scope\n" unless (
$classdata{Scope} eq $pack );
my $ptr = $classdata{MethodContext};
$ptr -> {Defaults} = {@_};
};
sub _Groups(@) # Takes in groups, returns an array ref
{
my $pack = caller; # get calling package
die "Attempt to define module outside of scope\n" unless (
$classdata{Scope} eq $pack );
my $ptr = $classdata{MethodContext};
$ptr -> {Groups} = [@_];
};
sub _With(&) # takes in code, returns ref to sub
{
my $pack = caller; # get calling package
die "Attempt to define module outside of scope\n" unless (
$classdata{Scope} eq $pack );
my $ptr = $classdata{MethodContext};
$ptr -> {Code} = shift;
};
};
1;
1.1 p5ee/P5EEx/Beige/P5EEx/Beige/ModuleTest.pm
Index: ModuleTest.pm
===================================================================
#!/usr/local/perl/bin
# Hello.
package ModuleTest;
print "fred";
sub import
{
# my $pack = (caller(0))[0];
my $pack = caller;
print "dOUG";
print $pack;
print keys %{ $pack."::" };
*{ $pack."::TestSub" } = sub { print "hello" };
#*{${ $pack."::" }}{TestSub} = sub { print "Hello" };
#*{{$pack."::"}}{"TestSub"} = sub { print "Hello" };
return 1;
};
1;
1.1 p5ee/P5EEx/Beige/P5EEx/Beige/ModuleTestDemo.pl
Index: ModuleTestDemo.pl
===================================================================
#!/usr/local/perl/bin
use ModuleTestDemo;
'ModuleTestDemo' -> TestSub();
<STDIN>;
1;