in reply to Search and substitute into data structures

Substitution is conceptually a destructive operation, particularly on structures, and that is how you use it, so I would rewrite your unwrap_cdata as explicitly so:

use strict; use warnings; use Data::Dumper; my $var = '<Country>&lt;![CDATA[US]]&gt;</Country>'; unwrap_cdata($var); print $var."\n"; my $hash = { america => '<Country>&lt;![CDATA[US]]&gt;</Country>', europe => ['<Country>&lt;![CDATA[IT]]&gt;</Country>','<Co +untry>&lt;![CDATA[UK]]&gt;</Country>'], }; print Dumper $hash; unwrap_cdata($hash); print Dumper $hash;

If you ever really want to make copies, pass the copies to unwrap_cdata instead, and make sure you make deep copies (like with Storable::dclone).

And now for my trick:

sub unwrap_cdata { for (@_) { eval { unwrap_cdata(@$_); 1 } and next; eval { unwrap_cdata(values %$_); 1 } and next; s/<!\[CDATA\[//; s/&lt;!\[CDATA\[//; s/]]>//; s/]]&gt;//; } }

Recursion is fun. Block eval is great fun. :-)

print "Just another Perl ${\(trickster and hacker)},"
The Sidhekin proves Sidhe did it!

Replies are listed 'Best First'.
Re^2: Search and substitute into data structures
by rbi (Monk) on Apr 30, 2007 at 19:26 UTC
    Thanks! And what about wrap_cdata, to wrap the content with <![CDATA ]> in the approach of your trick ?

      Thanks! And what about wrap_cdata, to wrap the content with [I assume] <![CDATA[ ]]> in the approach of your trick ?

      Same thing, as long as you know how to do it with a single string. Perhaps something like this:

      sub wrap_cdata { for (@_) { eval { wrap_cdata(@$_); 1 } and next; eval { wrap_cdata(values %$_); 1 } and next; s/(?<![^>])([^<]+)/<![CDATA[$1]]>/g; } }

      Or not. I don't know why your original unwrap did not use the /g modifier. So please, season to taste.

      print "Just another Perl ${\(trickster and hacker)},"
      The Sidhekin proves Sidhe did it!