Re: Non-destructive string substitution
by fruiture (Curate) on Apr 20, 2004 at 18:29 UTC
|
The key is to copy the data you want to preserve. If you need this kind of behaviour very often, write a simple subroutine that does what you want.
sub cdo(&$){
local $_ = $_[1];
$_[0]->();
$_
}
my $foo = 'abc';
print cdo { s/abc/def/ } $foo;
print "\n$foo\n";
TI, of course, MTOWTDI.
| [reply] [d/l] |
Re: Non-destructive string substitution
by japhy (Canon) on Apr 20, 2004 at 17:59 UTC
|
This is one way:
map { s/this/that/; $_ } do { $str };
You can substitute [$str]->[0] for do { $str } if you'd like.
_____________________________________________________
Jeff [japhy]Pinyan:
Perl,
regex,
and perl
hacker, who'd like a job (NYC-area)
s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??;
| [reply] [d/l] [select] |
|
This doesn't work either:
my $foo = "foo";
print map {s/foo/bar/g; $_} do{$foo};
print "\n$foo\n";
prints
bar
bar
This, however, does:
my $foo = "foo";
print map {s/foo/bar/g; $_} @{[$foo]};
print "\n$foo\n";
| [reply] [d/l] [select] |
|
Hmm. The debugger runs them differently. Oh well. Regardless, if you don't mind stringification, you can use "$foo" as the argument to map().
_____________________________________________________
Jeff [japhy]Pinyan:
Perl,
regex,
and perl
hacker, who'd like a job (NYC-area)
s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??;
| [reply] [d/l] [select] |
Re: Non-destructive string substitution
by Fletch (Bishop) on Apr 20, 2004 at 17:44 UTC
|
print do { (my $t = $_ ) =~ s/foo/bar/g };
Update: Ah, missed the without temp variables qualifier. You could use the similar do { local($_)=$_; s/foo/bar/g }, which uses the block's stack rather than an explicit temporary.
| [reply] [d/l] [select] |
Re: Non-destructive string substitution
by QM (Parson) on Apr 20, 2004 at 19:16 UTC
|
Does this generalize into a quest for an anonymous scalar? [Note: the OP is asking for new scalar either way -- only the name is eschewed.]
Is there any benefit to avoiding the named temp variable? Speed? Obfu?
I would prefer to see the autodocumenting nature of
($bar = $foo) =~ s/foo/bar/g;
In many cases the new value will be caught in another variable anyway. I'm guessing 'no temp' is only interesting if the value is passed to another operator/function immediately, like print or perldoc:length, for instance.
It's also not a trivial exercise to devise a correctly formed Benchmark that demonstrates the difference.
-QM
--
Quantum Mechanics: The dreams stuff is made of
| [reply] [d/l] |
Re: Non-destructive string substitution
by kvale (Monsignor) on Apr 20, 2004 at 17:49 UTC
|
This code seems to do what you want
my $foo = 'foofoofoo';
print map {s/foo/bar/g; $_} ($foo);
Update: No it doesn't, as $foo is still modified. I don't see a way.
-Mark
| [reply] [d/l] |
Re: Non-destructive string substitution
by sgifford (Prior) on Apr 20, 2004 at 18:08 UTC
|
You could write a sub that would create the temp variable for you and return it:
#!/usr/bin/perl -w
use strict;
foreach my $str (qw(fish apple license gradual canaan))
{
print sr($str,'s/([aeiou])/\u$1/g'),"\n";
}
sub sr
{
my($in,$re)=@_;
eval "\$in =~ $re;";
$@ and die "Bad regex '$re'\n";
$in;
}
although a temp variable is still being created, just not explicitly.
This is probably the best you're going to be able to do (although there's probably a way to do it without eval), since doing something nondestructively means that the original must be kept intact, so there have to be two copies of the variable.
| [reply] [d/l] [select] |
Re: Non-destructive string substitution
by EdwardG (Vicar) on Apr 20, 2004 at 18:59 UTC
|
| [reply] |
Re: Non-destructive string substitution
by ysth (Canon) on Apr 20, 2004 at 20:18 UTC
|
$ perl -we'$foo = "abcdefghij"; ($bar) = grep s/[ei]/x/g, "$foo"; prin
+t $bar'
abcdxfghxj
(If I ever get my act together, I hope to implement
$bar = $foo =~ s/[ei]/x/gr, but that will
modify $foo as well as returning it as $bar.) | [reply] [d/l] [select] |
|
my $s = "hi, how are you?";
my $s2 = ($s =~ s/,.*//gr);
print "$s2 \n$s\n";
__OUTPUT__
hi
hi, how are you?
hop this helps :) | [reply] [d/l] [select] |