/[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.4 - (hide annotations)
Thu Mar 27 15:17:03 2003 UTC (21 years, 3 months ago) by joko
Branch: MAIN
Changes since 1.3: +7 -2 lines
namespace fixes for Data::Mungle::*

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

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