700 Software
700 Software

Reputation: 87793

Find and replace without storing variable

Is there a way to do this in one line?

my $b = &fetch();
$b =~ s/find/replace/g;
&job($b)

Upvotes: 3

Views: 929

Answers (3)

mfontani
mfontani

Reputation: 2964

Sure, with a do {} block:

use strict;
use warnings;

sub fetch { 'please find me' }
sub job   { print @_, "\n"   }

job( do { $_ = fetch(); s/find/replace/g; $_ } );

The reason being that in Perl you cannot do fetch() =~ s/find/replace/;:
Can't modify non-lvalue subroutine call in substitution (s///) at ...

Perl 5.14 will introduce the /r flag (which makes the regex return the string with substitutions rather than the number of substitutions) and will reduce the above to:

job( do { $_ = fetch(); s/find/replace/gr; } );

edited thanks to FM: can shorten the above to:

job( map { s/find/replace/g; $_ } fetch() );

And once Perl 5.14 will be out it can be shortened to:

job( map { s/find/replace/gr } fetch() );

Upvotes: 4

Eric Strom
Eric Strom

Reputation: 40152

for (fetch() . '') {   # append with '' to make sure it is a non-constant value
    s/find/replace/g;
    job($_)
}

or use apply from one of the List modules:

use List::Gen qw/apply/;

job( apply {s/find/replace/g} fetch() );

Upvotes: 0

Michael Goldshteyn
Michael Goldshteyn

Reputation: 74390

If you are asking whether you have to go through a scalar variable to do the replace, the answer is yes. This is because the result of the substitution has to be stored somewhere. Also, the substitution does not return the variable used, it returns the number of substitutions made. Therefore, you can't inline it (i.e., &job($b =~ s/find/replace/g) ) in the function call.

Upvotes: 4

Related Questions