Class-CompiledC
view release on metacpan or search on metacpan
lib/Class/CompiledC.pm view on Meta::CPAN
package Class::CompiledC;
=head1 NAME
Class::CompiledC
=cut
use 5.008007;
use strict;
use warnings;
use Carp;
use base qw/Attribute::Handlers/;
use Inline;
use Exporter qw/import/;
=head1 VERSION
This document describes version 2.21 of Class::CompiledC,
released Fri Oct 27 23:28:06 CEST 2006 @936 /Internet Time/
=cut
our $VERSION = 2.21;
our %includes;
our %funcs;
our %extfuncs;
our %code;
our %scheduled;
our %types;
our %EXPORT_TAGS;
our @EXPORT_OK;
our $re_ft;
our $re_ft_isa;
sub __circumPrint($$$);
sub __include;
sub __baseref($$);
sub __hashref($);
sub __arrayref($);
sub __coderef($);
sub __fetchSymbolName($);
sub __promoteFieldTypeToMacro($);
sub __parseFieldType;
$re_ft = qr/^(?:\s*)(int|float|number|string|ref|arrayref|hashref|
coderef|object|regexpref|any|uint)(?:\s*)/xi;
$re_ft_isa = qr/^(?:\s*)isa(?:\s*)\((?:\s*)([\w:]*)(?:\s*)\)(?:\s*)/i;
=head1 ABSTRACT
Class::CompiledC -- use C structs for your objects.
=head1 SYNOPSIS
package Foo;
use strict;
use warnings;
use base qw/Class::CompiledC/;
sub type : Field(String);
sub data : Field(Hashref);
sub count : Field(Int);
sub callback : Field(Coderef);
sub size : Field(Float);
sub dontcare : Field(Number);
sub dumper : Field(Isa(Data::Dumper));
sub items : Field(Arrayref);
sub notsure : Field(Object);
my $x;
$x = Foo->new(-type => "example",
-data => {},
-count => 0,
-callback => sub { print "j p " ^ " a h " ^ " " x 4 while 1},
-size => 138.4,
-dontcare => 12,
-dumper => Data::Dumper->new,
-items => [qw/coffee cigarettes beer/],
-notsure => SomeClass->new
);
=head1 DESCRIPTION
Note: Documentation is incomplete, partly outdated, of poor style and full of
typos. I need a ghostwriter.
Class::CompiledC creates classes which are based on C structs, it does this by
generating C code and compiling the code when your module is compiled (1). You
can add constraints on the type of the data that can be stored in the instance
variables of your objects by specifiying a C<field type> (i call instance
variables fields because it's shorter). A field without constraints are declared
by using the C<: Field> attribute (2) on a subroutine stub (3) of the name you
would like to have for your field eg. C<sub Foo : Field;> this would generate a
field called 'foo' and it's accesor method, also called 'foo' If you want to add
a constraint to the field just name the type as a parameter for the attribute eg
lib/Class/CompiledC.pm view on Meta::CPAN
{
__baseref $_[0], 'HASH';
}
=head3 __arrayref
__arrayref REFERENCE
Type: Subroutine.
Export: on request.
Prototype: $
Determines if REFERENCE is actually a array reference.
Utitlizes C<__baseref>.
=cut
sub __arrayref($)
{
__baseref $_[0], 'ARRAY';
}
=head3 __coderef
__coderef REFERENCE
Type: Subroutine.
Export: on request.
Prototype: $
Determines if REFERENCE is actually a code reference.
Utitlizes C<__baseref>.
=cut
sub __coderef($)
{
__baseref($_[0], 'CODE')
}
=head3 __fetchSymbolName
__fetchSymbolName GLOBREF
Type: Subroutine.
Export: on request.
Prototype: $
Returns the Symbol name from the glob reference GLOBREF.
Croaks if GLOBREF acutally isn't a glob reference.
=cut
sub __fetchSymbolName($)
{
no strict 'refs';
my $symbol = shift;
__baseref $symbol, 'GLOB' or croak 'not a GLOB reference';
return *$symbol{NAME};
}
=head3 __promoteFieldTypeToMacro
__promoteFieldTypeToMacro FIELDTYPE
Type: Subroutine.
Export: on request.
Prototype: none
Takes a fieldtype specfication, and returns a C<C> macro for doing the test.
Does not handle parametric types like C<isa>. See C<__parseFieldType> for that.
=cut
sub __promoteFieldTypeToMacro($)
{
my $type = shift;
return '' unless ($type);
return '' if ($type =~ /^any$/i);
return sprintf '__CHECK(__IS%s(__ARG0), "%s")', uc $type, $type;
}
=head3 __parseFieldType
__parseFieldType FIELDTYPE
Type: Subroutine.
Export: on request.
Prototype: none
Takes a fieldtype specfication, and returns a C<C> macro for doing the test.
Handles all field types. Delegates most work to the C<__promoteFieldTypeToMacro>
subroutine.
=cut
sub __parseFieldType
{
local $_ = shift;
if (/$re_ft/)
{
# warn sprintf "yeah %s !", __promoteFieldTypeToMacro $1;
return __promoteFieldTypeToMacro($1);
}
elsif (/$re_ft_isa/)
{
croak "fail0r: isa type needs a classname argument\n" unless $1;
return '__CHECK(__ISA(__ARG0, '."\"$1\"), \"__ISA\")";
}
else
{
croak "fail0r: bad type specified $_\n";
}
}
=head3 Include
sub Foo : C(...) Include(<math.h>)
sub Foo : Field(...) Include("bar.h")
Type: Attribute Handler
Export: no.
=cut
sub Include : ATTR(CODE, BEGIN)
{
my $package;
my $symbol;
my $ref;
my $attribute;
my $data;
$package = shift || croak "no package supplied";
$symbol = shift || croak "no symbol supplied";
$ref = shift || croak "no reference supplied";
$attribute = shift || croak "no attribute supplied";
$data = shift || croak "no includes supplied";
$data = [ $data ] unless __arrayref $includes{$package};
$includes{$package} = [] unless __arrayref $data;
push @{$includes{$package}}, @{$data};
}
=head3 C
sub Foo : C(RETVAL, ARG0, ...)
Type: Attribute Handler
Export: no.
=cut
sub C : ATTR(CODE, CHECK, RAWDATA)
{
my $package;
my $symbol;
my $attribute;
my $data;
lib/Class/CompiledC.pm view on Meta::CPAN
$data ? eval "use $data" : eval "use ${package}::Method::${name}";
bless *{$symbol}{CODE}, ($data || "${package}::Method::${name}");
return;
}
=head2 Inheritance
Class::CompiledC inherits the following methods from it's ancestors
=over
=item methods inherited from C<Attribute::Handlers>
=over
=item C<import>
=item C<_resolve_lastattr>
=item C<DESTROY>
=item C<_gen_handler_AH_>
=item C<_apply_handler_AH_>
=back
=back
=head2 Export
Class::CompiledC does not export anything by default but has a number of subroutines
to Export on request.
=head2 Export Tags
Class::CompiledC defines the following export tags:
=over
=item ref Subroutines to verify the type of references
=item misc miscellanous subroutines
=item field specification subroutines
=item intern miscellanous subroutines with low value outside this package
=item all Everything.
=back
=cut
BEGIN
{
$EXPORT_TAGS{ref} = [qw/__arrayref __coderef __hashref/];
$EXPORT_TAGS{misc} = [qw/__fetchSymbolName __baseref __circumPrint/];
$EXPORT_TAGS{field} = [qw/__parseFieldType __promoteFieldTypeToMacro/];
$EXPORT_TAGS{intern} = [qw/__include/];
$EXPORT_TAGS{all} = [map {@{$_}} values %EXPORT_TAGS ];
}
=head2 Exportable Symbols
The following subroutines are (im|ex)portable, either explicitly by name or
as part of a tag.
=over
=item C<__include>
=item C<__arrayref>
=item C<__coderef>
=item C<__hashref>
=item C<__fetchSymbolName>
=item C<__baseref>
=item C<__circumPrint>
=item C<__parseFieldType>
=item C<__promoteFieldTypeToMacro>
=back
=cut
BEGIN
{
@EXPORT_OK = @{$EXPORT_TAGS{all}};
}
=head1 EXAMPLES
TODO
=head1 DIAGNOSTICS
=over
=item C<no package supplied>
this message is usually caused by an class method called as a subroutine.
I<fatal error>
=item C<no target package supplied>
Some methods (and subroutines, btw) need a target package to operate on,
it seems that the argument is missing, or has evaluated to false value, which
very unlikely to be valid.
I<fatal error>
=item C<no code supplied>
This message is is caused by the __addCode method, which renders useless
without a supplied code argument.
I<fatal error>
=item C<no type supplied>
This message is caused by the __addCode method, when called without a type
argument. The __addCode method can only operate with a valid type argument.
Currently valid types are C<base> and C<ext> but more may be added in future.
I<fatal error>
=item C<bad type supplied>
This message is caused by the __addCode method, when called with a invalid type
argument. Currently valid types are C<base> and C<ext>
but more may be added in future.
I<fatal error>
=item C<fail0r: isa type needs a classname argument>
This message is caused by the __parseFieldType subroutine. The __parseFieldType
subroutine (which gets called by the Field attribute handler) found C<isa> as
type but without a classname. A is a check doesn't make sense without a
classname. If you just want to make sure that it is a object, you may use
C<Isa(Universal)> or (generally faster and shorter) C<Object>.
I<fatal error>
lib/Class/CompiledC.pm view on Meta::CPAN
=item *serious code cleanup
I still find too much things that are done the fast way instead of the right
way, this really bothers me.
=item *outsourcing
A few things need to be outsourced right away. I just don't know where to put
them. Especially the stuff not related to classes should be placed somewhere
else. The utility __.* subs (not methods!) could be placed in a different
package and locally (or maybe lexically?) imported, to avoid namespace pollution
of subclasses.
Random thought: lexical importing ? what a cute idea! is this possible?
=back
=head1 SEE ALSO
=over
=item TODO
=back
=head1 AUTHOR
blackhat.blade
The Hive
blade@focusline.de
=head1 COPYRIGHT
Copyright (c) 2005, 2006
blackhat.blade The Hive. All Rights Reserved.
This module is free software. It may be used, redistributed
and/or modified under the terms of the Artistic license.
=cut
1;
__END__
2.14 Wed Jan 18 00:44:39 CET 2006 @31 /Internet Time/
everything till here...
2.15 Thu Jan 19 20:28:41 CET 2006 @853 /Internet Time/
fixed documentation issues, the Field type for regular exprssions
is C<Regexpref> and I<not> C<Regexref>. I also had Regexenref in mind...
2.16 Sun Oct 08 00:05:19 CEST 2006 @962 /Internet Time/
fixed (?:Array|Code|Hash)ref type checking code
2.17 Sat Oct 21 01:01:45 CEST 2006 @1 /Internet Time/
added a few sanity checks for __fetchSymbolName
2.18 Sun Oct 22 13:21:16 CEST 2006 @514 /Internet Time/
fixed some serious bugs concerning refcounts of non ref values
fixed (?:Array|Code|Hash)ref type checking code
2.19 Sun Oct 22 19:52:04 CEST 2006 @786 /Internet Time/
relocated field type parsing into __genBaseCode in anticipation to support
introspection
refactored __promoteFieldTypeToMacro sub
adapted __addParentFields to emit only valid field types
added inspect method, it returns a hashref with fieldnames as keys and
field types as values. (you may change that hash but don't expect any
changes to persist, or even to propagate back and change the class on the
fly, we are not at this point, and we're not going into this directon)
2.20 Thu Oct 26 21:48:22 CEST 2006 @866 /Internet Time/
first public release
renamed to Class::CompiledC to avoid the creation of a new root namespace
added version requirement for 5.8.7, sorry for this but I cannot tell if
it will run with earlier versions.
2.21 Fri Oct 27 23:27:38 CEST 2006 @935 /Internet Time/
no code changes, fixed errors in Makefile.pl
2.22 Sun Oct 29 22:52:42 CET 2006 @953 /Internet Time/
updated documentation,
minor code cleanups.
( run in 0.500 second using v1.01-cache-2.11-cpan-e1769b4cff6 )