Class-OOorNO-0.011/ 0040755 0000764 0001040 00000000000 07607251354 013330 5 ustar tommy unknown Class-OOorNO-0.011/t/ 0040755 0000764 0001040 00000000000 07607251354 013573 5 ustar tommy unknown Class-OOorNO-0.011/t/4_export_ok.t 0100644 0000764 0001040 00000001320 07603243346 016204 0 ustar tommy unknown
use strict;
use Test;
# use a BEGIN block so we print our plan before module is loaded
BEGIN { use Class::OOorNO }
BEGIN { plan tests => scalar(@Class::OOorNO::EXPORT_OK), todo => [] }
BEGIN { $| = 1 }
# load your module...
use lib './';
# we gonna see if'n it cun export wut itz 'pose ta. this checks the
# @EXPORT_OK of all packages in the inheritance cascade, which is the
# only reason we're doing this. we already know that it UNIVERSAL::can do
# all its own methods if this test is being run. test 3 ensures that.
# this is just an automated non-empty superclass test
use Class::OOorNO @OOorNO::EXPORT_OK;
map {
ok ref(UNIVERSAL::can('Class::OOorNO', $_)) eq 'CODE'
} @Class::OOorNO::EXPORT_OK;
exit;
Class-OOorNO-0.011/t/3_can.t 0100644 0000764 0001040 00000000720 07607251274 014740 0 ustar tommy unknown
use strict;
use Test;
# use a BEGIN block so we print our plan before MyModule is loaded
BEGIN { plan tests => 6, todo => [] }
BEGIN { $| = 1 }
# load your module...
use lib './';
use Class::OOorNO;
my($f) = Class::OOorNO->new();
# check to see if non-autoloaded Class::OOorNO methods are can-able ;O)
map { ok(ref(UNIVERSAL::can($f,$_)),'CODE') } qw
(
coerce_array
myargs
myself
OOorNO
shave_opts
VERSION
);
exit;
Class-OOorNO-0.011/t/2_isa.t 0100644 0000764 0001040 00000000511 07603243770 014746 0 ustar tommy unknown
use strict;
use Test;
# use a BEGIN block so we print our plan before MyModule is loaded
BEGIN { plan tests => 1, todo => [] }
BEGIN { $| = 1 }
# load your module...
use lib './';
use Class::OOorNO;
my($f) = Class::OOorNO->new();
# check to see if Class::OOorNO ISA [foo, etc.]
ok(UNIVERSAL::isa($f,'Class::OOorNO'));
exit; Class-OOorNO-0.011/t/1_canuseit.t 0100644 0000764 0001040 00000000412 07603243676 016011 0 ustar tommy unknown
use strict;
use Test;
# use a BEGIN block so we print our plan before MyModule is loaded
BEGIN { plan tests => 1, todo => [] }
# load your module...
use lib './';
use Class::OOorNO;
# check object constructor
ok(ref(Class::OOorNO->new()),'Class::OOorNO');
exit; Class-OOorNO-0.011/t/5_empty_subclass.t 0100644 0000764 0001040 00000001157 07603244052 017233 0 ustar tommy unknown
use strict;
use Test;
# use a BEGIN block so we print our plan before module is loaded
BEGIN { use Class::OOorNO qw( :all ) }
BEGIN { plan tests => scalar(@Class::OOorNO::EXPORT_OK), todo => [] }
BEGIN { $| = 1 }
# load your module...
use lib './';
# automated empty subclass test
# subclassClass::OOorNO in package _Foo
package _Foo;
use strict;
use warnings;
$Foo::VERSION = 0.00_0;
@_Foo::ISA = qw( Class::OOorNO );
1;
# switch back to main package
package main;
# see if _Foo can do everything thatClass::OOorNO can do
map {
ok ref(UNIVERSAL::can('_Foo', $_)) eq 'CODE'
} @Class::OOorNO::EXPORT_OK;
exit;
Class-OOorNO-0.011/README 0100644 0000764 0001040 00000004101 07607251076 014202 0 ustar tommy unknown Class::OOorNO version 0.01_1
============================
DESCRIPTION
Transparently handles @_ for your class methods whether they were
called in OO style or not.
CHANGES IN LAST FEW RELEASES
(listed in reverse cronological order by date and subversion)
0.01_1
1/9/03, 4:42 am
Significant, thorough documentation updates. Various tweaks applied
to class methods based on comments from adrianh.
0.01_0
12/28/02, 1:54 am
Even more documentation completed. Fixed an egregious flaw found in
two methods:
Class::OOorNO::myargs()
Class::OOorNO::myself()
0.00_9
12/28/02, 12:45 am
A little more documentation completed. Completed move to namespace
Class::OOorNO from the errantly pre-assigned root namespace of OOorNO.
0.00_8
12/27/02, 5:50 pm
Much documentation has been added. Various methods have been corrected
to use a much stricter policy for determining whether or not a given
method was called in OO or procedural style. More in-depth discussion
regarding this issue is covered in the new documentation.
0.00_7
12/27/02, 11:08 am
Method Class::OOorNO::shave_opts() now uses UNIVERSAL::isa() rather than
CORE::ref() to check for an array ref as it should have in the beginning.
0.00_6
12/23/02, 2:01 pm
Miscellaneous optimizations
0.00_5
12/23/02, 2:47 am
Initial release of Class::OOorNO.pm
INSTALLATION
To install this module type the following:
perl Makefile.PL
make
make test
make install
On windows machines use nmake rather than make; those running cygwin don't have
to worry about this. If you don't know what cygwin is, use nmake and check out
after you're done installing this module if you want
to find out.
DEPENDENCIES
None.
AUTHOR
Tommy Butler
COPYRIGHT
Copyright (C) Tommy Butler 2001-2003, all rights reserved.
LICENCE
This library is free software, you may redistribute it and/or modify it
under the same terms as Perl itself.
Class-OOorNO-0.011/COPYING 0100644 0000764 0001040 00000000155 07575432312 014360 0 ustar tommy unknown This library is free software, you may redistribute it and/or modify it
under the same terms as Perl itself.
Class-OOorNO-0.011/MANIFEST 0100644 0000764 0001040 00000000211 07605760362 014452 0 ustar tommy unknown COPYING
Changes
MANIFEST
Makefile.PL
OOorNO.pm
OOorNO.pod
README
t/1_canuseit.t
t/2_isa.t
t/3_can.t
t/4_export_ok.t
t/5_empty_subclass.t
Class-OOorNO-0.011/OOorNO.pm 0100644 0000764 0001040 00000004302 07607243542 014775 0 ustar tommy unknown package Class::OOorNO;
use strict;
use vars qw( $VERSION @ISA @EXPORT_OK %EXPORT_TAGS );
use Exporter;
$VERSION = 0.01_1; # 2/30/02, 1:50 am
@ISA = qw( Exporter );
@EXPORT_OK = qw( OOorNO myargs myself coerce_array shave_opts );
%EXPORT_TAGS = ( 'all' => [ @EXPORT_OK ] );
# --------------------------------------------------------
# Constructor
# --------------------------------------------------------
sub new { bless({ }, shift(@_)) }
# --------------------------------------------------------
# Class::OOorNO::Class::OOorNO()
# --------------------------------------------------------
sub OOorNO { return($_[0]) if UNIVERSAL::isa($_[0],'UNIVERSAL') }
# --------------------------------------------------------
# Class::OOorNO::myargs()
# --------------------------------------------------------
sub myargs { shift(@_) if UNIVERSAL::isa($_[0], (caller(0))[0]); @_ }
# --------------------------------------------------------
# Class::OOorNO::myself()
# --------------------------------------------------------
sub myself { UNIVERSAL::isa($_[0], (caller(0))[0]) ? $_[0] : undef }
# --------------------------------------------------------
# Class::OOorNO::shave_opts()
# --------------------------------------------------------
sub shave_opts {
my($mamma) = myargs(@_);
return undef unless UNIVERSAL::isa($mamma,'ARRAY');
my(@maid) = @$mamma; @$mamma = ();
my($opts) = {};
while (@maid) {
my($o) = shift(@maid)||'';
if (substr($o,0,2) eq '--') {
$opts->{[split(/=/o,$o)]->[0]} = [split(/=/o,$o)]->[1] || $o;
}
else {
push(@$mamma, $o);
}
}
return($opts);
}
# --------------------------------------------------------
# Class::OOorNO::coerce_array()
# --------------------------------------------------------
sub coerce_array {
my($hashref) = {};
my($i) = 0;
my(@shadow) = myargs(@_);
while (@shadow) {
my($name,$val) = splice(@shadow,0,2);
if (defined($name)) {
$hashref->{$name} = (defined($val)) ? $val : '';
}
else {
++$i;
$hashref->{qq[un-named key no. $i]} = (defined($val)) ? $val : '';
}
}
return($hashref);
}
1;
Class-OOorNO-0.011/OOorNO.pod 0100644 0000764 0001040 00000035463 07607242312 015151 0 ustar tommy unknown
=pod
=head1 NAME
Class::OOorNO - Give your module classic I OO interfaces
=head1 STATUS!
This is a developer's release, and is not intended for use in the public sector.
This code is made available for developers who wish to aid in the furthering of
the code.
This is I a registered module in the CPAN module list. It is not part of
the CPAN yet.
=head1 SYNOPSIS
=over
=item B programming interface
package Your::Class;
use Class::OOorNO qw( coerce_array );
=item B programming interface
package Your::Class;
use Class::OOorNO;
my($obj) = Class::OOorNO->new();
=item B
package Your::Class;
use vars qw( @ISA );
use Class::OOorNO;
@ISA = qw( Class::OOorNO );
=back
=head1 PURPOSE
Allows you set up your module so it can I provide a standard
interface as well as an object-oriented interface to its users.
=head1 DESCRIPTION
Class::OOorNO helps your module handle the input for its subroutines
whether called in object-oriented style I<(as object methods or class methods
with the arrow syntax C<< -> >>)>, or in functional programming style
I<(as subroutines imported to the caller's namespace via L)>.
The bulk of this module comprises a lightweight, pure-Perl emulation of the
L library's C routine which is
written in C.
Devel::Caller dives deep into the internals of of the Perl interpreter
I<(see L)> to trace stack frames and can get the input for any call
in the stack. It's really handy for Iopment and debugging.
This module is much more lightweight and focuses more on your module's
I methods themselves.
=head1 EXPORT
None by default.
=head1 EXPORT_OK
All available methods. (see L below)
=head1 EXPORT_TAGS
C<:all> (exports all of C<@EXPORT_OK>)
=head1 METHODS
=head2 C
=over
=item I C
If your subroutine has been called as an object method, a reference to the
object will be returned. If your subroutine has been called as a class method,
the name of class itself will be returned as a string. Otherwise, a value of
undef is returned.
=back
=head2 C
=over
=item I C
If your subroutine has been called as an object method or as a class method, a
value of 1 will be returned, otherwise a false value (an empty string, eg- '')
will be returned.
=back
=head2 C
=over
=item I C
This method retrieves the input sent to your class methods and returns it
untouched, with the exception that if a blessed object reference from the same
namespace as the caller is found in $_[0], it will be not be included with
the rest of the arguments when they are returned. B that the
special variable C<"@_"> for your routine B in any way by
calling this method. You can still use and manipulate it as you normally would.
=item Purpose of C
This simply allows the methods in your class to get their argment list quickly
without having to check if they were called procedurally or with object-oriented
notation.
=over
=item I
B you are expecting a blessed object reference from your package to be in
C<$_[0]> regardless of the way your method was called -I
to get your arguments; that reference you're expecting will obviously be
excluded from the list you get back from C if you do.
=back
package Your::Class;
use Class::OOorNO qw( myargs );
sub bar {
my(@args) = myargs(@_);
...
B<-OR->
package Your::Class;
use Class::OOorNO;
our($onobj) = Class::OOorNO->new();
sub foo {
my(@args) = $onobj->myargs(@_);
...
=back
=head2 C
=over
=item I C
This method retrieves input sent to your class methods when called with
name-value pairs and returns an anonymous hash reference whose keys and values
correspond to the input argument names and their respective values. If nothing
is passed to it, an empty hash reference will be returned, eg- C<{ }>
package Your::Class;
use Class::OOorNO qw( coerce_array );
sub bar {
my($args) = coerce_array(@_);
...
B<-OR->
package Your::Class;
use Class::OOorNO;
our($onobj) = Class::OOorNO->new();
sub foo {
my($self) = shift(@_);
my($args) = $onobj->coerce_array(@_);
...
B<-OR->
package Your::Class;
use Class::OOorNO;
use vars qw( @ISA );
@ISA = qw( Class::OOorNO );
sub foo {
my($self) = shift(@_);
my($args) = $self->coerce_array(@_);
...
=item Purpose of C
It's common practice for Perl modules to accept name-value pairs for their
methods, and because @_ is an array it is easy to encounter warnings and errors
when this isn't handled correctly. An example of what this kind of call would
look like is shown below in the imaginary subroutine I<"Your::Class::method()">
Your::Class->method
(
-name => 'Joe',
-rank => 'Private, First-Class',
-SN => '87D91-35-713FOO',
);
=over
=item Avoids Common Pitfalls
Quite often a class method will use code such as this to handle name-value
paired input:
sub foo {
my($class) = shift;
my(%args) = @_; ...
B<-and/or->
sub bar {
my($args) = { @_ }; ...
=item What's Wrong With That?
While this practice is not evil, it can be error-prone in situations where:
=over
=item *
Your class method is called in procedural style and expects that the
first element in @_ is a blessed object reference.
=item *
Your class method is errantly called with an unbalanced set of name-value
pairs, or one or more named arguments get passed with undefined values.
=item *
You want to give your module the ability to export any or all of its methods
by using the L module, but still want to maintain an
object-oriented interface to your module as well. An example of a well known
module which does this is L. It is written to provide both a
standard procedural interface as well as an object-oriented one. You can
call its methods either way:
# object-oriented style
use CGI;
my($cgi_object) = CGI->new();
my($visitor) = $cgi_object->param('visitor name');
B<-OR->
# procedural style
use CGI qw( param );
my($visitor) = param('visitor name');
=back
=item Don't say I didn't I you B< ;o) >
When these situations occur, class methods sorting out name-value paired input
using the common problematic technique I<(demonstrated above in
"L)>" encounter problems such as undesired
program behavior, general errors, and warnings -both fatal and non-fatal.
Problems include:
=over
=item *
Argument sets that get reversed; the argument names become the hash values
and the argument values become the hash keys which is exactly the opposite of
the desired behavior.
=item *
The entire arument hash/hashref gets turned into a mess of mixed up
keys and values that don't reflect the actual input at all. Instead,
you get hash keys containing both argument names and argument values.
=item *
The argument hash/hashref is created with an uneven number of elements
and/or uninitialized values.
=back
Warnings I<(see L)> resulting from the above mentioned
situations could include any the following (Some of these don't apply unless
you run your program under the L) like you
I>.
=over
=item C
I
=item C
I
=item C
-where C<%s> is probably "HASH", though it could be complaining about a
non-reference to any data type that your routine may be attempting to treat
as a reference. This is often the result of a class method being called in
procedural style rather than in the object-oriented style using the arrow
C<-\>> syntax. The class method expects the first argument to be an object
reference, when it is clearly not. I<(This warning is fatal as well.)>
=item C
I, and will occur under the same circumstances
that surround the warning described immediately above. The class method
expects the first argument to be an object reference when it's not.
=back
=back
=back
=head2 C
=over
=item I C
I<-- Documentation for this method is not yet complete! -->
=back
=head1 EXAMPLES
B
=head2 using C
I
package Your::Module;
use strict;
use Exporter;
use vars qw( @EXPORT_OK );
@EXPORT_OK = qw( show_call_style );
use Class::OOorNO qw( OOorNO );
sub new { bless { }, shift }
sub show_call_style {
if (ref OOorNO(@_)) {
print __PACKAGE__ . "::foo was called as an OBJECT METHOD.\n"
}
elsif (OOorNO(@_)) {
print __PACKAGE__ . "::foo was called as an CLASS METHOD.\n"
}
else {
print __PACKAGE__ . "::foo was called as a SUBROUTINE.\n"
}
}
I
package main;
use strict;
use Your::Module qw( show_call_style );
my($YM) = Your::Module->new;
$YM->show_call_style; # as an object method
Your::Module->show_call_style; # as a class method
&Your::Module::show_call_style; # as a subroutine
&show_call_style; # as imported subroutine
I
Your::Module::foo was called as an OBJECT METHOD.
Your::Module::foo was called as an CLASS METHOD.
Your::Module::foo was called as a SUBROUTINE.
Your::Module::foo was called as a SUBROUTINE.
=head2 using C
I
package Your::Module;
use strict;
use Exporter;
use vars qw( @EXPORT_OK );
@EXPORT_OK = qw( print_self_name );
use Class::OOorNO qw( myself );
sub new { bless { }, shift }
sub print_self_name {
print( (ref myself(@_) || myself(@_) || __PACKAGE__), "\n" )
}
I
package main;
use strict;
use Your::Module qw( print_self_name );
my($YM) = Your::Module->new;
$YM->print_self_name; # as an object method
Your::Module->print_self_name; # as a class method
&Your::Module::print_self_name; # as a subroutine
print_self_name; # as imported subroutine
I
Your::Module
Your::Module
Your::Module
Your::Module
I
package Your::Module;
use strict;
use Exporter;
use vars qw( @EXPORT_OK );
@EXPORT_OK = qw( show_call_style get_self_ref );
use Class::OOorNO qw( OOorNO myself );
sub new { bless { }, shift }
sub show_call_style {
if (ref OOorNO(@_)) {
print __PACKAGE__ . "::foo was called as an OBJECT METHOD.\n"
}
elsif (OOorNO(@_)) {
print __PACKAGE__ . "::foo was called as an CLASS METHOD.\n"
}
else {
print __PACKAGE__ . "::foo was called as a SUBROUTINE.\n"
}
}
sub get_self_ref {
ref myself(@_) ? myself(@_) : __PACKAGE__->new
}
I
package main;
use strict;
use Your::Module qw( show_call_style get_self_ref );
my($YM) = Your::Module->new;
# supports calls that go way down the stack too:
Your::Module->new->get_self_ref->show_call_style;
Your::Module->get_self_ref->show_call_style;
&Your::Module::get_self_ref->show_call_style;
get_self_ref->show_call_style;
I
Your::Module::foo was called as an OBJECT METHOD.
Your::Module::foo was called as an OBJECT METHOD.
Your::Module::foo was called as an OBJECT METHOD.
Your::Module::foo was called as an OBJECT METHOD.
=head2 using C
I
package Your::Module;
use strict;
use Exporter;
use vars qw( @EXPORT_OK );
@EXPORT_OK = qw( print_argument_list );
use Class::OOorNO qw( myargs );
sub new { bless { }, shift }
sub print_argument_list {
print "My argument list: \n" . join("\n", myargs(@_)), "\n";
}
I
package main;
use strict;
use Your::Module qw( print_argument_list );
my($YM) = Your::Module->new;
my(@things) = ( 'foo',
12687.357,
$YM,
eval('*bar'),
[ 'baz', sub { "wubble" },
{ 'flarp' => 'wibble' } ] );
$YM->print_argument_list(@things); # as an object method
Your::Module->print_argument_list(@things); # as a class method
&Your::Module::print_argument_list(@things); # as a subroutine
print_argument_list(@things); # as imported subroutine
I
My argument list:
foo
12687.357
Your::Module=HASH(0x9bd858)
*main::bar
ARRAY(0x9bd954)
...repeated four times
=head2 using C
I
package Your::Module;
use strict;
use Exporter;
use vars qw( @EXPORT_OK );
@EXPORT_OK = qw( pass_name_value_pairs );
use Class::OOorNO qw( coerce_array );
sub new { bless { }, shift }
sub pass_name_value_pairs {
my($input) = coerce_array(@_);
my($driver) = $input->{'-driver'} || 'nobody';
my($car) = $input->{'-car'} || 'no car';
my($bike) = $input->{'-bike'} || 'no bike';
my($plane) = $input->{'-plane'} || 'no plane';
print("$driver drives $car, $bike, and $plane.\n");
}
I
I
=head2 using C
I
package Your::Module;
use strict;
use Exporter;
use vars qw( @EXPORT_OK );
@EXPORT_OK = qw( print_options );
use Class::OOorNO qw( shave_opts );
sub new { bless { }, shift }
sub print_options {
my($opts) = shave_opts(\@_);
print "\n",
( map { qq[$_ => $opts->{$_}] . "\n" } keys %$opts ),
"\n"
}
I
I
=head1 PREREQUISITES
None.
=head1 BUGS
This documentation isn't done yet, as you can see. This is being rectified
as quickly as possible. Please excercise caution if you choose to use this
code before it can be further documented for you. It is present on CPAN
at this time despite its unfinished condition in order to provide support for
the L module which lists Class::OOorNO among its
prerequisites. Please excuse the inconvenience.
=head1 AUTHOR
Tommy Butler >
=head1 COPYRIGHT
Copyright(c) 2001-2003, Tommy Butler. All rights reserved.
=head1 LICENSE
This library is free software, you may redistribute
and/or modify it under the same terms as Perl itself.
=head1 SEE ALSO
=over
=item L
=item L
=item L
=item L
=back
=cut
Class-OOorNO-0.011/Changes 0100644 0000764 0001040 00000002400 07607251122 014605 0 ustar tommy unknown Revision history for Perl extension Class::OOorNO.pm
0.01_1
1/9/03, 4:42 am
Significant, thorough documentation updates. Various tweaks applied
to class methods based on comments from adrianh.
0.01_0
12/28/02, 1:54 am
Even more documentation completed. Fixed an egregious flaw found in
two methods:
Class::OOorNO::myargs()
Class::OOorNO::myself()
0.00_9
12/28/02, 12:45 am
A little more documentation completed. Completed move to namespace
Class::OOorNO from the errantly pre-assigned root namespace of OOorNO.
0.00_8
12/27/02, 5:50 pm
Much documentation has been added. Various methods have been corrected
to use a much stricter policy for determining whether or not a given
method was called in OO or procedural style. More in-depth discussion
regarding this issue is covered in the new documentation.
0.00_7
12/27/02, 11:08 am
Method Class::OOorNO::shave_opts() now uses UNIVERSAL::isa() rather
than CORE::ref() to check for an array ref as it should have in the
beginning.
0.00_6
12/23/02, 2:01 pm
Miscellaneous optimizations
0.00_5
12/23/02, 2:47 am
Initial release of Class::OOorNO.pm
Class-OOorNO-0.011/Makefile.PL 0100644 0000764 0001040 00000001170 07603242756 015300 0 ustar tommy unknown use ExtUtils::MakeMaker;
require 5.6.0;
# See lib/ExtUtils/MakeMaker.pm for details of how to influence
# the contents of the Makefile that is written.
WriteMakefile
(
'ABSTRACT' => 'Handles "@_" for your own class methods',
'AUTHOR' => 'Tommy Butler ',
'INSTALLDIRS' => 'site',
'NAME' => 'Class::OOorNO',
'VERSION_FROM' => 'OOorNO.pm',
'linkext' => { LINKTYPE => '' }, # no link needed
'dist' =>
{
'COMPRESS' => 'gzip -9f',
'SUFFIX' => 'gz',
'ZIP' => '/usr/bin/zip',
'ZIPFLAGS' => '-rl',
}
);