Mr. Muskrat has asked for the wisdom of the Perl Monks concerning the following question:
As I mentioned in a previous post, I would like to be able to view the lvaluable function referred to by a reference instead of just the result of said function.
Say what?
Take this simple example: my $lvalue = \substr("abc", 1, 1); If you print the dereference (print $$lvalue,"\n";), you see the result 'b' and not the function that was called. I want to see 'substr("abc", 1, 1);'.
I originally thought that this would be extremely hard to accomplish but I started fiddling around with the B module and I eventually stumbled upon a way that seems to work quite well for most lvaluable functions.
The only lvaluable function that is really causing me problems is keys. I cannot get the exact code back that is referenced but I can come close. You see if someone were to reference keys %imahash = 5;, my code would spit out keys %hash = 7; because 1) I cannot resolve the hash name and 2) it shows the actual space allotted instead of what was asked for. #2 is not an issue in my book, in fact I see this as being better. #1 is the hard part and why I'm posting. Is this possible? What should I read?
Here is my example script. Please note that there may be many mistakes because I'm doing this via trial and error. I have not found the right set of documentation yet.
#!/usr/bin/perl -w use strict; use B; my $foo = ' delicious'; my $string = 'abcde'; my %imahash = ( key => 3, foo => $foo, string => $string, ); print "Testing vec:\n"; ltype(\(vec($foo, 0, 32) = 0x5065726C)); print "Testing keys:\n"; ltype(\(keys %imahash = 5)); print "Testing pos:\n"; ltype(\(pos $string = 3)); print "Testing pos:\n"; ltype(\(pos $string = 5)); print "Testing substr EXPR, OFFSET:\n"; ltype(\substr($string, 2)); print "Testing substr EXPR, OFFSET, LENGTH:\n"; ltype(\substr($string, 1, 2)); print "Done.\n"; sub enter { #print "Press any key to continue...\n"; # Original post print "Press Enter to continue...\n"; # Update $_=<STDIN>; } sub lvalue { my $ref = shift; my $lref = B::svref_2object($ref); return undef if $lref !~ /PVLV/; my $value = $$ref; my $type = $lref->TYPE; my $targ = $lref->TARG; my $string = $lref->TARG->PV; my $offset = $lref->TARGOFF; my $length = $lref->TARGLEN; print 'TYPE: ', $type,"\n"; my $func; if ($type eq 'x') { $func = 'substr("'.$string.'",'.$offset.','.$length.');'; } if ($type eq '.') { print "magic type: ", $targ->MAGIC->TYPE,"\n"; # 'g' $func = 'pos "'.$string.'" = '.$value.';'; } if ($type eq 'k') { $func = 'keys %hash = ' . $targ->MAX . ';'; =comment print $targ->FILL,"\n"; print $targ->MAX,"\n"; print $targ->KEYS,"\n"; print $targ->NAME,"\n"; print $targ->RITER,"\n"; print $targ->PMROOT,"\n"; =cut my %newhash = $targ->ARRAY; print "key\tvalue\t\t\tclass\ttrue value\n"; foreach my $key (keys %newhash) { my $class = B::class($newhash{$key}); print "$key\t$newhash{$key}\t$class\t",$newhash{$key}->$class,"\ +n"; } } if ($type eq 'v') { $func = "vec('$string',$offset,$length) = $value;"; } return $func; } sub ltype { my $lvalue = shift; print '$$lvalue: ',$$lvalue,"\n"; print lvalue($lvalue),"\n"; enter(); }
Update at author's req. - dvergin 2003-05-29
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Discovering the lvaluable function behind the reference
by diotalevi (Canon) on May 29, 2003 at 16:45 UTC | |
by Mr. Muskrat (Canon) on May 29, 2003 at 18:57 UTC | |
by diotalevi (Canon) on May 29, 2003 at 19:17 UTC | |
|
Re: Discovering the lvaluable function behind the reference
by educated_foo (Vicar) on May 29, 2003 at 16:49 UTC | |
|
Re: Discovering the lvaluable function behind the reference
by Mr. Muskrat (Canon) on Jun 03, 2003 at 17:43 UTC | |
by Mr. Muskrat (Canon) on Jun 04, 2003 at 14:31 UTC | |
|
Re: Discovering the lvaluable function behind the reference
by Mr. Muskrat (Canon) on Jun 03, 2003 at 15:44 UTC |