/[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.8 - (hide annotations)
Wed Feb 19 00:36:59 2003 UTC (21 years, 8 months ago) by joko
Branch: MAIN
Changes since 1.7: +11 -4 lines
+ bugfix: this {logger} is the instance itself, so has to be fed with ( level => xyz and namespace => xyz )
+ minor modifications in behaviour

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

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