/[cvs]/nfo/perl/libs/DesignPattern/Object.pm
ViewVC logotype

Annotation of /nfo/perl/libs/DesignPattern/Object.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.6 - (hide annotations)
Tue Feb 11 11:04:27 2003 UTC (21 years, 3 months ago) by joko
Branch: MAIN
Changes since 1.5: +25 -5 lines
+ metadata (args, caller, etc.) are now stored inside {__bridge}

1 joko 1.3 ## ---------------------------------------------------------------------------
2 joko 1.6 ## $Id: Object.pm,v 1.5 2003/02/09 16:24:46 joko Exp $
3 joko 1.3 ## ---------------------------------------------------------------------------
4 joko 1.2 ## $Log: Object.pm,v $
5 joko 1.6 ## Revision 1.5 2003/02/09 16:24:46 joko
6     ## + pseudo constructor mechanism by calling method 'constructor' on object instantiation
7     ##
8 joko 1.5 ## Revision 1.4 2003/01/22 17:56:49 root
9     ## + fix: just use the logger if it's available
10     ##
11 root 1.4 ## Revision 1.3 2003/01/20 16:54:22 joko
12     ## + sub fromPackage: refactored from libp's 'getNewPerlObjFromPkgName' or s.th.l.th.
13     ##
14 joko 1.3 ## Revision 1.2 2002/12/27 16:05:42 joko
15     ## + played with Devel::CallerItem and Devel::StackTrace
16     ##
17 joko 1.2 ## Revision 1.1 2002/12/13 21:46:29 joko
18     ## + initial check-in
19     ##
20 joko 1.3 ## ---------------------------------------------------------------------------
21 joko 1.1
22    
23     package DesignPattern::Object;
24    
25     use strict;
26     use warnings;
27 joko 1.2
28    
29     use Data::Dumper;
30     #use Devel::CallerItem;
31     #use Devel::StackTrace;
32    
33 joko 1.3
34     # get logger instance
35 root 1.4 my $logger = eval { Log::Dispatch::Config->instance; };
36 joko 1.3
37 joko 1.2 sub new {
38    
39     # the classname in most cases
40     my $classname = shift;
41    
42     # use already blessed reference, if passed in - else use the very classname
43     my $class = ref ($classname) || $classname;
44    
45 root 1.4 $logger->debug( "$classname->new( ... )" . "\t[via " . __PACKAGE__ . "]" ) if $logger;
46 joko 1.3
47 joko 1.2 # the base for our object - a plain perl hash, which ....
48     my $self = {};
49     # note:
50     # this makes an instance of an arbitrary perl variable,
51     # the most often used for this purpose is - guess it - the hash,
52     # since it resembles object-properties in a convenient way:
53     # $object->{property} = 'Hello World!';
54     # if you _do_ care about privacy you might take a look
55     # at CPAN's Tie::SecureHash or Class::Contract ... have fun!
56    
57     # TODO: what about logging in here? inherit from
58     # DesignPattern::Object::Logger for this purpose....
59     # ... or would this give us (harmful) circular module dependencies???
60     #$logger->debug( __PACKAGE__ . "->new( @args )" ); # this is not "common"!
61    
62    
63     # remember the stacktrace: abstract this out (DesignPattern::Object::Trace) or parametrize!
64     #my $trace = Devel::StackTrace->new();
65     #print Dumper($trace);
66     #print Dumper($trace->frame(1)->args());
67    
68     #print "args: ", $self->{'__caller'}->hasargs(), "\n";
69    
70     #print Dumper($self);
71     #exit;
72    
73 joko 1.3
74 joko 1.2 # argument-handling ...
75    
76     # ... get them ...
77     my @args = ();
78     @_ && (@args = @_);
79    
80     # ... check if we can coerce them into an array (this needs an even number of arguments)
81     my $argcount = $#args + 1;
82     my $fract = $argcount / 2;
83    
84     my $seperate = pop @args if $fract != int($fract);
85    
86     # mixin arguments
87     $self = { @args };
88    
89 joko 1.6 # scan for arguments prefixed by a double underscore '__'
90     foreach (keys %$self) {
91     if (/^__(.+?)$/) {
92     $self->{__bridge}->{$1} = $self->{$_};
93     delete $self->{$_};
94     }
95     }
96    
97     # mixin seperate - FIXME: should this not be done after blessing?
98     $self->{__bridge}->{'arg'} = $seperate if $seperate;
99 joko 1.2
100     # ... bless hash into object using classname
101     bless $self, $class;
102 joko 1.3
103     # remember the caller
104 joko 1.6 $self->{__bridge}->{caller_module} = caller;
105 joko 1.3 #print Dumper(caller(2));
106     #exit;
107    
108 joko 1.6 $self->{__bridge}->{class_name} = $classname;
109    
110     # patches for backward compatibility
111     $self->{'__arg'} = $self->{__bridge}->{'arg'} if $self->{__bridge}->{'arg'};
112     $self->{'__caller'} = $self->{__bridge}->{caller_module} if $self->{__bridge}->{caller_module};
113     $self->{'__classname'} = $self->{__bridge}->{class_name} if $self->{__bridge}->{class_name};
114 joko 1.3
115 joko 1.2 $self->_init() if $self->can('_init');
116 joko 1.5 $self->constructor() if $self->can('constructor');
117 joko 1.6
118     # trace
119     #print Dumper($self);
120     #exit;
121 joko 1.3
122 joko 1.2 return $self;
123     }
124 joko 1.1
125     sub _abstract_function {
126     my $self = shift;
127     my $self_classname = ref $self;
128     my $function_name = shift;
129     # was:
130 joko 1.3 $logger->warning( __PACKAGE__ . ": function '$function_name' is an abstract method, please implement it in '$self_classname'.");
131 joko 1.1 # is:
132 joko 1.3 #die( __PACKAGE__ . ": Function '$function_name' is an abstract method, please implement it in '$self_classname'.");
133 joko 1.1 #exit;
134 joko 1.3 }
135    
136     sub fromPackage {
137     my $self = shift;
138     #my $self_classname = ref $self;
139     my $pkgname = shift;
140     my @args = @_;
141     # my $args = shift;
142    
143     # my $caller = $self->{'__caller'};
144    
145     #print Dumper($args);
146    
147     $logger->debug( __PACKAGE__ . "->fromPackage( pkgname $pkgname args @args )" );
148    
149     # perl-load
150     my $evstring = "use $pkgname;";
151     eval($evstring);
152    
153     # report errors
154     if ($@) {
155     # build error-messages
156     my $errmsg_native = __PACKAGE__ . ':' . __LINE__ . " Error in eval \"$evstring\": " . $@;
157     #my $classname = $self->{__classname};
158     my $errmsg_critical = '';
159     if ($errmsg_native =~ m/Can't locate (.+?) in \@INC/) {
160     $errmsg_critical = "Could not instantiate object from package '$pkgname' - location of '$1' failed.";
161     } else {
162     $errmsg_critical = $errmsg_native;
163     }
164     # write error to logging-output (console|file|database)
165     $logger->debug( $errmsg_native );
166     $logger->critical( $errmsg_critical );
167     return;
168     }
169    
170     # object-creation
171     my $object = $pkgname->new(@args);
172    
173     # run boot-methods on object
174     $object->_init() if $object->can('_init');
175 joko 1.5 $object->constructor() if $object->can('constructor');
176 joko 1.3
177     return $object;
178 joko 1.1 }
179    
180     1;

MailToCvsAdmin">MailToCvsAdmin
ViewVC Help
Powered by ViewVC 1.1.26 RSS 2.0 feed