File Coverage

blib/lib/Class/Methods.pm
Criterion Covered Total %
statement 53 53 100.0
branch 3 4 75.0
condition n/a
subroutine 13 13 100.0
pod 0 5 0.0
total 69 75 92.0


line stmt bran cond sub pod time code
1             package Class::Methods;
2              
3 1     1   2082 use Devel::Pointer ();
  1         22360  
  1         175  
4              
5             require 5.005_62;
6 1     1   15 use strict;
  1         2  
  1         53  
7 1     1   7 use warnings;
  1         9  
  1         307  
8              
9             require Exporter;
10              
11             our @ISA = qw(Exporter);
12              
13             # Items to export into callers namespace by default. Note: do not export
14             # names by default without a very good reason. Use EXPORT_OK instead.
15             # Do not simply export all your public functions/methods/constants.
16              
17             # This allows declaration use Class::Methods ':all';
18             # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
19             # will save memory.
20             our %EXPORT_TAGS = ( 'all' => [ qw(
21            
22             ) ] );
23              
24             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
25              
26             our @EXPORT = qw(
27            
28             );
29             our $VERSION = '0.062';
30              
31             # class: returns this object's class.
32             sub class ($) {
33 7     7 0 10 my $self = shift;
34             # Return the anonymous class object of a given object.
35 7         30 return Devel::Pointer::unsmash_hv(substr(ref $self, 2+length(__PACKAGE__)));
36             }
37              
38             # extend: adds methods to this object's class.
39             sub extend ($;%) {
40 3     3 0 43 my $self = shift;
41             # Get the anonymous class object out of the object.
42 3         11 my $class = $self->class;
43             # To muddle with the symbol table, we have to turn some strict down.
44 1     1   5 no strict 'refs';
  1         2  
  1         204  
45             # While we have methods on the stack,
46 3         11 while (@_) {
47             # Get them off of the stack.
48 3         6 my($method, $coderef) = (shift, shift);
49             # Put them into the class object.
50 3         15 $class->{$method} = $coderef;
51             # And then into the symbol table.
52 3         4 *{__PACKAGE__ . "::" . (0+$class) . "::" . $method} = $coderef;
  3         24  
53             }
54             # We're done, give back the object we started with.
55 3         5 return $self;
56             }
57              
58             # remove: removes methods from this object's class
59             sub remove ($;@) {
60 1     1 0 48 my $self = shift;
61             # Get the anonymous class object out of the object.
62 1         3 my $class = $self->class;
63             # To muddle with the symbol table, we have to turn some strict down.
64 1     1   7 no strict 'refs';
  1         1  
  1         372  
65             # While we have methods on the stack,
66 1         12 while (@_) {
67             # Get them off of the stack.
68 1         2 my($method) = shift;
69             # Remove them from the class object.
70 1         3 delete $class->{$method};
71             # And then from the symbol table.
72 1         2 undef *{__PACKAGE__ . "::" . (0+$class) . "::" . $method};
  1         11  
73             }
74             }
75              
76             # base: tell this object's class to inherit from another class
77             sub base ($;@) {
78 3     3 0 9 my $self = shift;
79             # Get the anonymous class object out of the object.
80 3         6 my $class = class($self);
81             # Tell the new anonymous class to inherit from the passed modules.
82 1 100   1   7 { eval "package " . __PACKAGE__ . '::' . (0+$class) . "; use base qw(" . join(' ', map { ref($_) || $_ } @_) . ");" }
  1     1   2  
  1     1   114  
  1         6  
  1         2  
  1         50  
  1         4  
  1         2  
  1         504  
  3         7  
  3         12  
  3         216  
83             }
84              
85             # new: create and return a new object attached to a new (empty) class.
86             sub new ($;%) {
87             # I suppose I should care what package the user thinks we are, but I don't.
88 2     2 0 86 shift;
89             # Create our anonymous class.
90 2         3 my $class = {};
91             # Make it self-referential, so it stays around forever.
92 2         6 $class->{""} = $class;
93             # Bless the class object into its own (anonymous) class, for the moment, so we can use extend.
94 2         15 my $package = bless $class, __PACKAGE__ . '::' . (0+$class);
95             # Tell the new anonymous class to inherit from us.
96 2         8 base($class, __PACKAGE__);
97             # Add the user provided methods, if any.
98 2 50       17 $class->extend(@_) if @_;
99             # Return the package name of the newly created anonymous class.
100 2         7 return ref($class);
101             }
102              
103             1;
104             __END__