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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.6 - (show 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 ## ---------------------------------------------------------------------------
2 ## $Id: Object.pm,v 1.5 2003/02/09 16:24:46 joko Exp $
3 ## ---------------------------------------------------------------------------
4 ## $Log: Object.pm,v $
5 ## Revision 1.5 2003/02/09 16:24:46 joko
6 ## + pseudo constructor mechanism by calling method 'constructor' on object instantiation
7 ##
8 ## Revision 1.4 2003/01/22 17:56:49 root
9 ## + fix: just use the logger if it's available
10 ##
11 ## 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 ## Revision 1.2 2002/12/27 16:05:42 joko
15 ## + played with Devel::CallerItem and Devel::StackTrace
16 ##
17 ## Revision 1.1 2002/12/13 21:46:29 joko
18 ## + initial check-in
19 ##
20 ## ---------------------------------------------------------------------------
21
22
23 package DesignPattern::Object;
24
25 use strict;
26 use warnings;
27
28
29 use Data::Dumper;
30 #use Devel::CallerItem;
31 #use Devel::StackTrace;
32
33
34 # get logger instance
35 my $logger = eval { Log::Dispatch::Config->instance; };
36
37 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 $logger->debug( "$classname->new( ... )" . "\t[via " . __PACKAGE__ . "]" ) if $logger;
46
47 # 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
74 # 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 # 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
100 # ... bless hash into object using classname
101 bless $self, $class;
102
103 # remember the caller
104 $self->{__bridge}->{caller_module} = caller;
105 #print Dumper(caller(2));
106 #exit;
107
108 $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
115 $self->_init() if $self->can('_init');
116 $self->constructor() if $self->can('constructor');
117
118 # trace
119 #print Dumper($self);
120 #exit;
121
122 return $self;
123 }
124
125 sub _abstract_function {
126 my $self = shift;
127 my $self_classname = ref $self;
128 my $function_name = shift;
129 # was:
130 $logger->warning( __PACKAGE__ . ": function '$function_name' is an abstract method, please implement it in '$self_classname'.");
131 # is:
132 #die( __PACKAGE__ . ": Function '$function_name' is an abstract method, please implement it in '$self_classname'.");
133 #exit;
134 }
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 $object->constructor() if $object->can('constructor');
176
177 return $object;
178 }
179
180 1;

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