Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Strukturerhaltendes "Tiefen"-map

0 views
Skip to first unread message

Tobias Nissen

unread,
Nov 15, 2009, 6:07:43 AM11/15/09
to
Moin!

Ich habe ein fast inhaltsgleiches Posting schon gestern abgesetzt. Aber
irgendwie scheinen die NNTP-Server hier (Uni) zu spinnen. Google hat's
jedenfalls nicht, also nochmal über einen anderen Anbieter. Das gab mir
auch die Gelegenheit ein paar Sachen zu ändern.

Ich möchte eine Datenstruktur bestehend aus Strings, Arrays,
Array- und Hashreferenzen durchlaufen und Werte darin ändern. Also aus

$VAR1 = {
'eins' => 'zwei',
'drei' => 'vier',
'fünf' => [
'sechs', 'sieben', [
'acht',
{ 'neun' => 'zehn' }
]
]
};

soll dann etwa

$VAR1 = {
'eins' => 'ZWEI',
'drei' => 'VIER',
'fünf' => [
'SECHS', 'SIEBEN', [
'ACHT',
{ 'neun' => 'ZEHN' }
]
]
};

werden, wenn das Ziel ist, alle Strings in Großbuchstaben zu wandeln.
Welche Transformation dabei letztlich angewendet wird, soll natürlich
definierbar sein.

Strukturerhaltend soll hierbei heißen, dass sich alle Datentypen an der
gleichen Stelle wie vorher befinden¹ und dass auf Hashes wie vor der
Transformation zugegriffen werden kann (der Schlüssel soll also nicht
verändert werden). Ich mache das bisher mit folgendem rekursiven Code
(lauffähig unter http://paste.debian.net/51563/ verfügbar):

my $a = {
eins => 'zwei',
drei => 'vier',
'fünf' => [
'sechs',
'sieben',
[ 'acht', { neun => 'zehn' } ]
]
};

upupup($a);

sub upupup {
# fall 1, @_ ist ein array
return map {upupup($_)} @_ if scalar(@_) > 1;

# fall 2, @_ ist eine arrayreferenz
return [map {upupup($_)} @{$_[0]}]
if scalar(@_)==1 and ref($_[0]) eq 'ARRAY';

# fall 3, @_ ist eine hashreferenz
if (scalar(@_)==1 and ref($_[0]) eq 'HASH') {
foreach my $key (keys %{$_[0]}) {
$_[0]->{$key} = upupup($_[0]->{$key});
}
return $_[0];
}

# sonst ist @_ ein string
return uc($_[0]);
}

Der Code erfüllt die Aufgabenstellung, ist aber nicht schön. Dazu
einige Fragen:

1. Ich kann das doch nicht alles mit einem einzigen map abfrühstücken,
richtig? D.h. ich muss die Datenstruktur von Hand durchlaufen und
wieder eins zu eins zusammensetzen, ja? Mit anderen Worten, Perls
map verhält sich so, wie man's von map² erwartet?

2. Die if-Statements und das Hin- und Hercasten ist selten dämlich.
Geht das schöner?

3. Fall 3 geht sicherlich mit weniger Syntax. Aber kann man da auch ein
platzsparendes map benutzen? Ich sehe jedenfalls nicht wie.

4. Gibt es ein Modul welches diese Funktionalität (also eine Art
"Tiefenmap", etwa ein etwas abgespecktes foldr³) schon bietet?

Schöne Grüße!
Tobias

¹ die Reihenfolge der Hashes soll natürlich egal sein :-)
² http://en.wikipedia.org/wiki/Map_(higher-order_function)
³ http://en.wikipedia.org/wiki/Fold_(higher-order_function)

Tobias Nissen

unread,
Nov 15, 2009, 6:32:54 AM11/15/09
to
Tobias Nissen wrote:
[...]
> upupup($a);

Das ist so natürlich mit dem ursprünglichen Code Quark und funktioniert
nur mit der gegebenen Hashreferenz.

Ich wollte die Datenstruktur eigentlich gar nicht direkt mutieren. So
ist's besser (siehe http://paste.debian.net/51566/):

diff --git a/deepmap.pl_old b/deepmap.pl
index 8eff265..ea040cf 100644
--- a/deepmap.pl_old
+++ b/deepmap.pl
@@ -18,7 +18,7 @@ my $a = {

print "Vorher: ".Dumper($a);

-upupup($a);
+my $b = upupup($a);



sub upupup {
# fall 1, @_ ist ein array

@@ -30,15 +30,16 @@ sub upupup {



# fall 3, @_ ist eine hashreferenz
if (scalar(@_)==1 and ref($_[0]) eq 'HASH') {

+ my $newhashref;


foreach my $key (keys %{$_[0]}) {

- $_[0]->{$key} = upupup($_[0]->{$key});
+ $newhashref->{$key} = upupup($_[0]->{$key});
}
- return $_[0];
+ return $newhashref;


}

# sonst ist @_ ein string
return uc($_[0]);
}

-print "Nachher: ".Dumper($a);
+print "Nachher: ".Dumper($b);

Peter J. Holzer

unread,
Nov 15, 2009, 1:28:27 PM11/15/09
to
[Etwas viel gequotet, aber ich f�rchte, das ist f�r den Kontext
notwendig ist]

On 2009-11-15 11:07, Tobias Nissen <t...@movb.de> wrote:
> Ich m�chte eine Datenstruktur bestehend aus Strings, Arrays,
> Array- und Hashreferenzen durchlaufen und Werte darin �ndern. Also aus


>
> $VAR1 = {
> 'eins' => 'zwei',
> 'drei' => 'vier',

> 'f�nf' => [


> 'sechs', 'sieben', [
> 'acht',
> { 'neun' => 'zehn' }
> ]
> ]
> };
>
> soll dann etwa
>
> $VAR1 = {
> 'eins' => 'ZWEI',
> 'drei' => 'VIER',

> 'f�nf' => [


> 'SECHS', 'SIEBEN', [
> 'ACHT',
> { 'neun' => 'ZEHN' }
> ]
> ]
> };
>

> werden, wenn das Ziel ist, alle Strings in Gro�buchstaben zu wandeln.
> Welche Transformation dabei letztlich angewendet wird, soll nat�rlich
> definierbar sein.
>
> Strukturerhaltend soll hierbei hei�en, dass sich alle Datentypen an der


> gleichen Stelle wie vorher befinden� und dass auf Hashes wie vor der

> Transformation zugegriffen werden kann (der Schl�ssel soll also nicht
> ver�ndert werden). Ich mache das bisher mit folgendem rekursiven Code
> (lauff�hig unter http://paste.debian.net/51563/ verf�gbar):
[...]


> sub upupup {
> # fall 1, @_ ist ein array
> return map {upupup($_)} @_ if scalar(@_) > 1;
>
> # fall 2, @_ ist eine arrayreferenz
> return [map {upupup($_)} @{$_[0]}]
> if scalar(@_)==1 and ref($_[0]) eq 'ARRAY';
>
> # fall 3, @_ ist eine hashreferenz
> if (scalar(@_)==1 and ref($_[0]) eq 'HASH') {
> foreach my $key (keys %{$_[0]}) {
> $_[0]->{$key} = upupup($_[0]->{$key});
> }
> return $_[0];
> }
>
> # sonst ist @_ ein string
> return uc($_[0]);
> }
>

> Der Code erf�llt die Aufgabenstellung, ist aber nicht sch�n. Dazu
> einige Fragen:
>
> 1. Ich kann das doch nicht alles mit einem einzigen map abfr�hst�cken,


> richtig? D.h. ich muss die Datenstruktur von Hand durchlaufen und
> wieder eins zu eins zusammensetzen, ja? Mit anderen Worten, Perls

> map verh�lt sich so, wie man's von map� erwartet?

Ja.


> 2. Die if-Statements und das Hin- und Hercasten ist selten d�mlich.
> Geht das sch�ner?

1) Nach
return ... if scalar(@_) > 1;
kann @_ nur mehr 0 oder 1 Elemente haben. Wenn Du den Fall 0 Elemente
gleich abpr�fst, werden die Ifs schon einfacher.
2) Wo wird da gecastet? (Was ist �berhaupt ein cast in Perl?) Meinst Du
scalar? Oder die Dereferenzierungen @{...} und %{...}?
3) Variablen helfen das ganze �bersichtlicher zu machen.

Damit komme ich mal auf:

sub upupup {
# fall 1, 0 oder mindestens 2 Argumente
# in dem Fall rufen wir es einfach f�r jedes Argument auf:
return map {upupup($_)} @_ if scalar(@_) != 1;

# Wir haben genau ein Element:
my $e = $_[0];



# fall 2, @_ ist eine arrayreferenz

return [map {upupup($_)} @$e]
if ref($e) eq 'ARRAY';



# fall 3, @_ ist eine hashreferenz

if (ref($e) eq 'HASH') {
my $new;
foreach my $key (keys %$e) {
$new->{$key} = upupup($e->{$key});
}
return $new;


}

# sonst ist @_ ein string

return uc($e);
}


> 3. Fall 3 geht sicherlich mit weniger Syntax. Aber kann man da auch ein
> platzsparendes map benutzen? Ich sehe jedenfalls nicht wie.

$new = { map { $_ => upupup($e->{$_} } keys %$e };

Damit braucht man das $new nat�rlich nicht mehr und das wird zu:

sub upupup {
# fall 1, 0 oder mindestens 2 Argumente
# in dem Fall rufen wir es einfach f�r jedes Argument auf:
return map { upupup($_) } @_ if scalar(@_) != 1;

# Wir haben genau ein Element:
my $e = $_[0];



# fall 2, @_ ist eine arrayreferenz

return [ map { upupup($_) } @$e ] if ref($e) eq 'ARRAY';



# fall 3, @_ ist eine hashreferenz

return { map { $_ => upupup($e->{$_} } keys %$e } if (ref($e) eq 'HASH');



# sonst ist @_ ein string

return uc($e);
}

Fall 2 kann man noch durch

return [ upupup(@$e) ] if ref($e) eq 'ARRAY';

ersetzen, da genau dieses map ja in Fall 1 auch abgehandelt wird, aber
ich bin mir nicht sicher, ob das eleganter ist (eher w�rde ich
vorschreiben, dass upupup mit genau einem Parameter aufgerufen werden
muss).


> 4. Gibt es ein Modul welches diese Funktionalit�t (also eine Art


> "Tiefenmap", etwa ein etwas abgespecktes foldr�) schon bietet?

fold ist reduce (in List::Util). Aber ich glaube eher nicht, dass das
dadurch eleganter wird.

hp (der den Code jetzt leichtsinnigerweise ungetestet postet)

Tobias Nissen

unread,
Nov 15, 2009, 3:25:22 PM11/15/09
to
Peter J. Holzer wrote:
[...]
>> 2. Die if-Statements und das Hin- und Hercasten ist selten dämlich.
>> Geht das schöner?
[...]
> 2) Wo wird da gecastet? (Was ist überhaupt ein cast in Perl?) Meinst

> Du scalar? Oder die Dereferenzierungen @{...} und %{...}?

Du hast natürlich Recht, casts sind das nicht.

[...]


>> 3. Fall 3 geht sicherlich mit weniger Syntax. Aber kann man da auch
>> ein platzsparendes map benutzen? Ich sehe jedenfalls nicht wie.
>
> $new = { map { $_ => upupup($e->{$_} } keys %$e };

Ja, der Wald und die Bäume... Danke!

> Damit braucht man das $new natürlich nicht mehr und das wird zu:


>
> sub upupup {
> # fall 1, 0 oder mindestens 2 Argumente

> # in dem Fall rufen wir es einfach für jedes Argument auf:


> return map { upupup($_) } @_ if scalar(@_) != 1;
>
> # Wir haben genau ein Element:
> my $e = $_[0];
>
> # fall 2, @_ ist eine arrayreferenz
> return [ map { upupup($_) } @$e ] if ref($e) eq 'ARRAY';
>
> # fall 3, @_ ist eine hashreferenz
> return { map { $_ => upupup($e->{$_} } keys %$e } if (ref($e) eq 'HASH');
>
> # sonst ist @_ ein string
> return uc($e);
> }

Super, vielen Dank. Das sieht doch schon viel freundlicher aus.

> Fall 2 kann man noch durch
>
> return [ upupup(@$e) ] if ref($e)
> eq 'ARRAY';
>
> ersetzen, da genau dieses map ja in Fall 1 auch abgehandelt wird, aber

> ich bin mir nicht sicher, ob das eleganter ist (eher würde ich


> vorschreiben, dass upupup mit genau einem Parameter aufgerufen werden
> muss).

Ich beziehe mich auf den Inhalt der Klammer: Du meinst man schränkt sie
auf Referenzen auf Arrays oder Hashes ein? Dann kommt man sicher nicht
um eine zweite Funktion herum. _Aber_: Kann's sein, dass ich es auf
Referenzen einschränken muss, wenn ich es idiotensicher haben möchte?
Wenn da nun jemand ein Hash (keine Hashreferenz) reintut, dann werden
die Schlüssel ja verändert. Und dabei fällt mir gerade auf, dass ich
gar nicht weiß, wie ich herausfinde, ob mir da jemand ein Hash und kein
Array gegeben hat. Geht das überhaupt?

>> 4. Gibt es ein Modul welches diese Funktionalität (also eine Art


>> "Tiefenmap", etwa ein etwas abgespecktes foldr³) schon bietet?
>
> fold ist reduce (in List::Util). Aber ich glaube eher nicht, dass das
> dadurch eleganter wird.

Ne, stimmt, man muss ja doch jeden Fall abhandeln. In den Sprachen in
denen man am meisten fold()et hat man ja meist nur Elemente und Listen
von Elementen, da beschränkt's sich ja meist auf höchstens zwei Fälle.

> hp (der den Code jetzt leichtsinnigerweise ungetestet postet)

Ach, der geht so durch... Vielen dank nochmal!

Joerg

unread,
Nov 15, 2009, 3:38:09 PM11/15/09
to
Am 15.11.2009 12:07 schrieb Tobias Nissen:
> Ich m�chte eine Datenstruktur bestehend aus Strings, Arrays,
> Array- und Hashreferenzen durchlaufen und Werte darin �ndern. Also aus

>
> $VAR1 = {
> 'eins' => 'zwei',
> 'drei' => 'vier',
> 'f�nf' => [

> 'sechs', 'sieben', [
> 'acht',
> { 'neun' => 'zehn' }
> ]
> ]
> };
>
> soll dann etwa
>
> $VAR1 = {
> 'eins' => 'ZWEI',
> 'drei' => 'VIER',
> 'f�nf' => [

> 'SECHS', 'SIEBEN', [
> 'ACHT',
> { 'neun' => 'ZEHN' }
> ]
> ]
> };
Hallo Tobias,
mit
use Data::Dumper;
$VAR2=eval(uc(Dumper($VAR1)));

kannst Du Deine gesamte Struktur in Gro�buchstaben umwandeln. Sollen die
Keys so bleiben, wie sie sind, baust Du Dir eine kleine Funktion, die
das uc ersetzt und tust sie in das eval. Diese Zeile sollte es dann tun:

$VAR2=eval(join("", map{sub{s/(.*=>)*(.*)/$1\U$2/; $_}->($_)}
split(/\r/, Dumper($VAR1))));


J�rg

Wolf Behrenhoff

unread,
Nov 15, 2009, 7:14:43 PM11/15/09
to
Tobias Nissen schrieb:

> Ich beziehe mich auf den Inhalt der Klammer: Du meinst man schränkt sie
> auf Referenzen auf Arrays oder Hashes ein? Dann kommt man sicher nicht
> um eine zweite Funktion herum. _Aber_: Kann's sein, dass ich es auf
> Referenzen einschränken muss, wenn ich es idiotensicher haben möchte?
> Wenn da nun jemand ein Hash (keine Hashreferenz) reintut, dann werden
> die Schlüssel ja verändert. Und dabei fällt mir gerade auf, dass ich
> gar nicht weiß, wie ich herausfinde, ob mir da jemand ein Hash und kein
> Array gegeben hat. Geht das überhaupt?

Jein.

Es geht nicht, wenn du tatsächlich die Parameter "normal" übergibst und
auch anonyme Werte übergeben möchtest. Ansonsten kannst du die Übergabe
als Referenz aber mit Hilfe von Prototypen erzwingen, ohne dass der
Benutzer deiner Funktion extra den \ schreiben müsste - da haben wir
doch tatsächlich mal einen nützlichen Zweck von den Prototypen gefunden!
Das geht so:

sub upupup(\[$@%]) {
print "Ich wurde aufgerufen mit: ", ref shift, "\n";
}

my %h = (42 => 23);
my @a = (2,3,5,7,11);
my $s = "simpel";

upupup(@a);
upupup(%h);
upupup($s);

Was dann aber nicht mehr geht, ist ein Aufruf mit einem Wert, also
upupup("hallo") - aber das ergibt in deinem Fall ja sowieso keinen Sinn.

- Wolf

Tobias Nissen

unread,
Nov 16, 2009, 2:41:44 AM11/16/09
to
Wolf Behrenhoff wrote:
> Tobias Nissen schrieb:
[is_a_hash() in Perl]

>> Geht das überhaupt?
>
> Jein.
>
> Es geht nicht, wenn du tatsächlich die Parameter "normal" übergibst
> und auch anonyme Werte übergeben möchtest. Ansonsten kannst du die
> Übergabe als Referenz aber mit Hilfe von Prototypen erzwingen, ohne
> dass der Benutzer deiner Funktion extra den \ schreiben müsste - da
> haben wir doch tatsächlich mal einen nützlichen Zweck von den
> Prototypen gefunden! Das geht so:
>
> sub upupup(\[$@%]) {
> print "Ich wurde aufgerufen mit: ", ref shift, "\n";
> }

Danke, gedacht habe ich mir gestern schon sowas, fand's dann aber etwas
zu friemelig. So wie Du es aufschreibst sieht es ja aber gar nicht mehr
so wild aus. Meine erste Reaktion war allerdings: Schön ist das nicht.
Als eingefleischter Perler mag man das "normal" finden. Aber warum darf
ref() mehr wissen als wir, warum gibt es kein direktes is_a_hash()?

Ist das eine der zahlreichen Inkonsistenzen von Perl 5 oder liegt's an
mir? Die meisten Programmiersprachen kennen nur Listen und einzelne
Elemente als elementare Datenstrukturen. Aber da weiß man immer, woran
man ist. Ein Hash /ist/ in Perl aber eine elementare Datenstruktur.
Diese basiert zwar auf Listen mit einer geraden Zahl von Elementen,
aber das interessiert den Programmierer ja in der Regel nicht. Ich habe
so das Gefühl, Skalare und Arrays sind first-class-citizens, Hashes
aber nur second-class. Das stört beim Programmieren recht wenig, wenn
man es erstmal verstanden hat. Aber ganz sauber finde ich das nicht.
Wie sehen die alten Hasen das?

Macht Perl 6 das anders?

Moritz Lenz

unread,
Nov 16, 2009, 1:29:36 PM11/16/09
to
Tobias Nissen wrote:
> Danke, gedacht habe ich mir gestern schon sowas, fand's dann aber etwas
> zu friemelig. So wie Du es aufschreibst sieht es ja aber gar nicht mehr
> so wild aus. Meine erste Reaktion war allerdings: Schön ist das nicht.
> Als eingefleischter Perler mag man das "normal" finden. Aber warum darf
> ref() mehr wissen als wir, warum gibt es kein direktes is_a_hash()?
>
> Ist das eine der zahlreichen Inkonsistenzen von Perl 5 oder liegt's an
> mir? Die meisten Programmiersprachen kennen nur Listen und einzelne
> Elemente als elementare Datenstrukturen. Aber da weiß man immer, woran
> man ist. Ein Hash /ist/ in Perl aber eine elementare Datenstruktur.
> Diese basiert zwar auf Listen mit einer geraden Zahl von Elementen,
> aber das interessiert den Programmierer ja in der Regel nicht. Ich habe
> so das Gefühl, Skalare und Arrays sind first-class-citizens, Hashes
> aber nur second-class. Das stört beim Programmieren recht wenig, wenn
> man es erstmal verstanden hat. Aber ganz sauber finde ich das nicht.
> Wie sehen die alten Hasen das?
>
> Macht Perl 6 das anders?

Jein. Es gibt keinen Hash-Kontext in Perl 6, aber ansonsten ist der Hash
genauso fundamental wie das Array in Perl 6. Du kannst auch solche
Spässe machen:

sub foo(@array, %hash, $scalar) {
# hier mit %hash etc. arbeiten
}

Ein Hash im List-Kontext gibt in Perl 6 nicht mehr eine Liste key und
value abwechselnd zurück (kann man aber mit %hash.kv immer noch haben,
wenn man will), sondern eine Liste von Pair-Objekten, das erleichtert
den Umgang in einigen Fällen schon ziemlich.

Grüße,
Moritz

--
Moritz Lenz
http://perl-6.de/ http://moritz.faui2k3.org/

Peter J. Holzer

unread,
Nov 16, 2009, 4:22:09 PM11/16/09
to
On 2009-11-16 07:41, Tobias Nissen <t...@movb.de> wrote:
> Wolf Behrenhoff wrote:
>> Tobias Nissen schrieb:
> [is_a_hash() in Perl]
>>> Geht das �berhaupt?
>>
>> Jein.
>>
>> Es geht nicht, wenn du tats�chlich die Parameter "normal" �bergibst
>> und auch anonyme Werte �bergeben m�chtest. Ansonsten kannst du die
>> �bergabe als Referenz aber mit Hilfe von Prototypen erzwingen, ohne
>> dass der Benutzer deiner Funktion extra den \ schreiben m�sste - da
>> haben wir doch tats�chlich mal einen n�tzlichen Zweck von den

>> Prototypen gefunden! Das geht so:
>>
>> sub upupup(\[$@%]) {
>> print "Ich wurde aufgerufen mit: ", ref shift, "\n";
>> }
>
> Danke, gedacht habe ich mir gestern schon sowas, fand's dann aber etwas
> zu friemelig. So wie Du es aufschreibst sieht es ja aber gar nicht mehr
> so wild aus. Meine erste Reaktion war allerdings: Sch�n ist das nicht.

> Als eingefleischter Perler mag man das "normal" finden. Aber warum darf
> ref() mehr wissen als wir, warum gibt es kein direktes is_a_hash()?

ref wei� gar nicht mehr als wir. Der Prototyp sorgt nur daf�r, eine
Referenz auf das (einzige) Argument �bergeben wird. Man schreibt also


upupup(%h);

und der Compiler macht daraus

upupup(\%h);

Innerhalb der Funktion ist dann $_[0] einfach eine Referenz auf %h,
genauso als ob man upupup(\%h) ohne Prototyp aufgerufen h�tte. Ist nur
syntaktischer Zucker, inhaltlich �ndert sich nichts.

Du kannst kein Hash an eine Funktion �bergeben, weil Ceine Funktion immer
eine Liste von Skalaren als Argumente erwartet. Wenn Du sowas schreibst (ohne
Prototyp):

upupup(%h);

dann wird %h im Listenkontext ausgewertet, d.h., Du bekommst eine Liste
die aus den keys und den zugeh�rigen Werten besteht.

Im Prinzip passiert auch bei Arrays das gleiche, nur dass dass eine
Liste der Elemente eines Arrays nicht so leicht vom Array selbst zu
unterscheiden ist. Aber man merkt es z.B., wenn man zwei Arrays an eine
Funktion �bergibt:

upupup(@a, @b);

@_ in upupup enh�lt dann die Konkatenation der Elemente von @a und @b.
Wo @a aufh�rt und @b beginnt, kann nicht mehr festgestellt werden.

> Ist das eine der zahlreichen Inkonsistenzen von Perl 5 oder liegt's an
> mir?

Inkonsistent ist es nicht. Etwas beschr�nkt ist es halt.

hp

Lamprecht

unread,
Nov 21, 2009, 4:55:06 AM11/21/09
to Tobias Nissen
Tobias Nissen schrieb:

> Ich m�chte eine Datenstruktur bestehend aus Strings, Arrays,
> Array- und Hashreferenzen durchlaufen und Werte darin �ndern. Also aus


>
> $VAR1 = {
> 'eins' => 'zwei',
> 'drei' => 'vier',

> 'f�nf' => [


> 'sechs', 'sieben', [
> 'acht',
> { 'neun' => 'zehn' }
> ]
> ]
> };
>
> soll dann etwa
>
> $VAR1 = {
> 'eins' => 'ZWEI',
> 'drei' => 'VIER',

> 'f�nf' => [


> 'SECHS', 'SIEBEN', [
> 'ACHT',
> { 'neun' => 'ZEHN' }
> ]
> ]
> };
>

> werden, wenn das Ziel ist, alle Strings in Gro�buchstaben zu wandeln.
> Welche Transformation dabei letztlich angewendet wird, soll nat�rlich
> definierbar sein.
>

use strict;
use warnings;

package MyVisitor;
use Moose;
extends 'Data::Visitor';

sub visit_value{
$_[1] = uc $_[1] ;
}


package main;
use Data::Dumper;
my $VAR1 = {


'eins' => 'zwei',
'drei' => 'vier',

'f�nf' => [


'sechs', 'sieben', [
'acht',
{ 'neun' => 'zehn' }
]
]
};

my $v = MyVisitor->new;
$v->visit($VAR1);

print Dumper $VAR1;

Gr��e, Christoph

Tobias Nissen

unread,
Nov 21, 2009, 5:11:43 AM11/21/09
to
Lamprecht wrote:
> Tobias Nissen schrieb:
>> Ich möchte eine Datenstruktur bestehend aus Strings, Arrays,
>> Array- und Hashreferenzen durchlaufen und Werte darin ändern. Also

>> aus
>>
>> $VAR1 = {
>> 'eins' => 'zwei',
>> 'drei' => 'vier',
>> 'fünf' => [

>> 'sechs', 'sieben', [
>> 'acht',
>> { 'neun' => 'zehn' }
>> ]
>> ]
>> };
>>
>> soll dann etwa
>>
>> $VAR1 = {
>> 'eins' => 'ZWEI',
>> 'drei' => 'VIER',
>> 'fünf' => [

>> 'SECHS', 'SIEBEN', [
>> 'ACHT',
>> { 'neun' => 'ZEHN' }
>> ]
>> ]
>> };
>>
>> werden, wenn das Ziel ist, alle Strings in Großbuchstaben zu

>> wandeln. Welche Transformation dabei letztlich angewendet wird,
>> soll natürlich definierbar sein.
[...]

> extends 'Data::Visitor';
>
> sub visit_value{
> $_[1] = uc $_[1] ;
> }
[...]

> my $v = MyVisitor->new;
> $v->visit($VAR1);

Nice, danke! :-) Hätte mich eigentlich auch gewundert, wenn's da nicht
schon was von Ratio^W^W im CPAN gegeben hätte.

0 new messages