/[cvs]/nfo/perl/libs/Data/Mungle/Code/Ref.pm
ViewVC logotype

Annotation of /nfo/perl/libs/Data/Mungle/Code/Ref.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.5 - (hide annotations)
Thu Mar 27 15:31:03 2003 UTC (21 years, 3 months ago) by joko
Branch: MAIN
Changes since 1.4: +5 -2 lines
fixes to modules regarding new namespace(s) below Data::Mungle::*

1 root 1.1 ## ---------------------------------------------------------------------------
2 joko 1.5 ## $Id: Ref.pm,v 1.4 2003/03/27 15:17:03 joko Exp $
3 root 1.1 ## ---------------------------------------------------------------------------
4 joko 1.2 ## $Log: Ref.pm,v $
5 joko 1.5 ## Revision 1.4 2003/03/27 15:17:03 joko
6     ## namespace fixes for Data::Mungle::*
7     ##
8 joko 1.4 ## Revision 1.3 2003/02/20 19:33:28 joko
9 joko 1.5 ## refactored code from Data.Transform.Deep
10 joko 1.4 ## + sub ref_slot
11     ## + sub expr2perl
12     ##
13 joko 1.3 ## Revision 1.2 2003/02/20 18:55:46 joko
14     ## + minor cosmetic update
15     ##
16 joko 1.2 ## Revision 1.1 2003/01/22 17:59:22 root
17     ## + refactored from Mail::Audit::Dispatch
18     ##
19 root 1.1 ## ---------------------------------------------------------------------------
20    
21    
22 joko 1.4 package Data::Mungle::Code::Ref;
23 root 1.1
24     use strict;
25     use warnings;
26    
27     require Exporter;
28     our @ISA = qw( Exporter );
29     our @EXPORT_OK = qw(
30 joko 1.3 &get_coderef
31     &ref_slot
32 root 1.1 );
33    
34    
35     sub get_coderef {
36     my $codepack = shift;
37     my $method = shift;
38     $codepack || return '[error]';
39     $method ||= '';
40     $method && ($codepack .= '::');
41     return eval '\&' . $codepack . $method . ';';
42     }
43 joko 1.3
44    
45     # this function seems to do similar stuff like these below (refexpr2perlref & co.)
46     # TODO: maybe this mechanism can be replaced completely through some nice module from CPAN .... ? ;-)
47     sub _ref_slot_bylist {
48     my $var = shift;
49     my $indexstack_ref = shift;
50     my @indexstack = @{$indexstack_ref};
51     my $joiner = '->';
52     my @evlist;
53     foreach (@indexstack) {
54     my $elem;
55     if ($_ =~ m/\d+/) { $elem = "[$_]"; }
56     if ($_ =~ m/\D+/) { $elem = "{$_}"; }
57     push @evlist, $elem;
58     }
59     my $evstring = join($joiner, @evlist);
60     $evstring = 'return $var->' . $evstring . ';';
61     #print "ev: $evstring\n";
62     return eval($evstring);
63     }
64    
65    
66     sub ref_slot {
67    
68     my $obj = shift;
69     my $expr = shift;
70     my $values = shift;
71     my $delimiter = shift;
72    
73     $delimiter ||= '->';
74    
75     my $value;
76     # detect for callback (code-reference)
77     if (ref($expr) eq 'CODE') {
78     $value = &$expr($obj);
79    
80     } elsif (ref($expr) eq 'ARRAY') {
81     return _ref_slot_bylist($obj, $expr);
82    
83     } elsif ($expr =~ m/$delimiter/) {
84     # use expr as complex object reference declaration (obj->subObj->subSubObj->0->attribute)
85     (my $objPerlRefString, my $parts) = expr2perl($expr, $delimiter);
86    
87     # trace
88     #print "expr: $expr", "\n";
89     #print "objPerlRefString: $objPerlRefString", "\n";
90    
91     my $evstr = '$obj' . '->' . $objPerlRefString;
92    
93     # trace
94     #print "eval: $evstr", "\n";
95    
96     $value = eval($evstr);
97     die ($@) if $@;
98    
99     # if value isn't set, try to set it
100     my $callbackMap;
101     if ($values) {
102     #if (ref $values eq 'HASH') {
103     if (ref $values eq 'Data::Map') {
104     $callbackMap = $values->getAttributes();
105     } else {
106     # apply $values as single value to referenced slot
107     #print "APPLY!", "\n";
108     eval('$obj' . '->' . $objPerlRefString . ' = $values;');
109     die ($@) if $@;
110     }
111     }
112    
113     # determine $values - if it's a hashref, use it as a "valueMap"
114     # "fallback" to callbackMap
115     # callbacks are applied this way:
116     # take the last element of the expression parts and check if this string exists as a key in the callback-map
117     if (!$value && $callbackMap) {
118     #print Dumper($callbackMap);
119    
120     # prepare needle
121     my @parts = @$parts;
122     my $count = $#parts;
123     my $needle = $parts[$count];
124    
125     # prepare haystack
126     my @haystack = keys %$callbackMap;
127     if (grep($needle, @haystack)) {
128     $value = $callbackMap->{$needle}->();
129     #print "value: ", $value, "\n";
130     }
131     }
132    
133     } else {
134     # use expr as simple scalar key (attributename)
135     $value = $obj->{$expr};
136     }
137    
138     return $value;
139    
140     }
141    
142    
143     sub expr2perl {
144     my $expr = shift;
145     my $delimiter = shift;
146    
147     $delimiter = quotemeta($delimiter);
148    
149     # split expression by dereference operators first
150     my @parts_pure = split(/$delimiter/, $expr);
151    
152     # wrap []'s around each part, if it consists of numeric characters only (=> numeric = array-index),
153     # use {}'s, if there are word-characters in it (=> alphanumeric = hash-key)
154     my @parts_capsule = @parts_pure;
155     map {
156     m/^\d+$/ && ($_ = "[$_]") || ($_ = "{$_}");
157     } @parts_capsule;
158    
159     # join parts with dereference operators together again and return built string
160     return (join('->', @parts_capsule), \@parts_pure);
161     }
162    
163 root 1.1
164     1;
165 joko 1.2 __END__

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