/[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.7 - (hide annotations)
Tue Feb 18 18:34:35 2003 UTC (21 years, 3 months ago) by joko
Branch: MAIN
Changes since 1.6: +40 -10 lines
+ fix: just logs if possible (sub log_basic)

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

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