1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
| # -*- Mode: cperl; coding: utf-8; tab-width: 8; indent-tabs-mode: nil; cperl-indent-level: 4 -*-
# test3.pl
use strict;
use warnings;
use utf8;
use Data::Dumper;
package Prefix;
sub TIEHANDLE {
my ($class, $prefix) = @_;
my $self = { prefix => $prefix, text => ''};
bless $self, $class
}
sub PRINT {
my $self = shift;
for (split /(\n)/, join '', @_) {
if (m/\n/) {
print "$self->{prefix}$self->{text}\n";
$self->{text} = ''
} else {
$self->{text} .= $_
}
}
}
sub CLOSE {
my $self = shift;
print "$self->{prefix}$self->{text}\n" and $self->{text} = '' if $self->{text}
}
sub UNTIE {
my $self = shift;
$self->CLOSE;
}
package Prefix::Guard;
sub new {
my ($class, $glob, $prefix) = @_;
tie *$glob, 'Prefix', $prefix;
bless { glob => $glob}, $class;
}
DESTROY {
my $self = shift;
my $glob = $self->{glob};
untie *$glob;
}
package module1;
use Data::Dumper;
sub F1(@) {
my $function = (caller(0))[3];
my $rc = 12;
my $var1 = 'toto';
my $var2 = 'titi';
my $var3 = 'tutu';
my $var4 = 'tata';
my $var5 = 2000;
my @list1 = qw/foo bar baz/;
my %hash1 = (qux => 'xyzzy');
($var1) = @_;
{
my $guard = Prefix::Guard->new( *F1, "[F1 avant F2] ");
print F1 +Data::Dumper->Dump([$var1, $var2, $var3, $var4, $var5, \@list1, \%hash1], [qw(*var1 *var2 *var3 *var4 *var5 *list1 *hash1)]);
}
$rc=module2::F2({ function => $function, param1 => $var1 });
{
my $guard = Prefix::Guard->new( *F1, "[F1 après F2] ");
print F1 +Data::Dumper->Dump([$var1, $var2, $var3, $var4, $var5, \@list1, \%hash1], [qw(*var1 *var2 *var3 *var4 *var5 *list1 *hash1)]);
}
return $rc;
}
package module2;
use PadWalker;
sub F2(@) {
my $function=(caller(0))[3];
my ($refArg)=@_;
my $guard = Prefix::Guard->new( *F2, '[F2] ');
if ($refArg->{param1} eq 'toto') {
print F2 "La fonction ".$refArg->{function}." envoi bien ce qu'il faut ".$refArg->{param1}."\n";
return 0;
} else {
print F2 "Ça ne va pas du tout, je sors l'artillerie.\n";
# Je voudrai ici obtenir en lecture le contenu de module1::F1::var1 à var5, sans les nommer, pour faire un truc du style :
my $up = 1;
++$up while ((caller($up))[3] ne $refArg->{function});
module3::F3(PadWalker::peek_my($up));
return 12;
}
return 4;
}
package module3;
use Data::Dumper;
sub F3(@) {
my $function=(caller(0))[3];
my ($refArg)=@_;
tie *F3, 'Prefix', '[F3] ';
# Faire ce qu'il faut ici pour réparer l'objet avec les valeurs de la pile de variables
print F3 "faire ce qu'il faut avec " . Dumper($refArg);
print F3 "ces variables sont insensées : on les remet dans le droit chemin\n";
for (qw($var1 $var2 $var3 $var4 $var5 @list1 %hash1)) {
my $name = $_;
for ($refArg->{$name}) {
if (ref eq 'SCALAR') {
print F3 " on corrige $name de '${$_}'";
${$_} = reverse ${$_};
print F3 " en '${$_}'\n";
next;
}
if (ref eq 'ARRAY') {
print F3 " on corrige $name de (@{$_})";
@{$_} = reverse @{$_};
print F3 " en (@{$_})\n";
next;
}
if (ref eq 'HASH') {
my @l = %{$_};
print F3 " on corrige $name de (@l)";
%{$_} = reverse %{$_};
@l = %{$_};
print F3 " en (@l)\n";
next;
}
}
}
return 0;
}
package main;
module1::F1('die die die'); |
Partager