tags:

views:

84

answers:

3

Is there a way to do this in one line?

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

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.

Michael Goldshteyn
In Java I can send the result of `replaceAll(regex)` directly into the job subroutine. I was hoping it could be done in Perl. I will wait awhile before I give up.
cjavapro
cjavapro, the Java approach will also require intermediate memory storage of the result, only that it's behind the scenes.
Emil Vikström
+4  A: 

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() );
mfontani
Upvote for the info on Perl 5.14; this is why I read answers to questions I think I already know, because sometime you still learn even when you DID know! Now if only we could get Ubuntu to deliver something newer than 5.10.1.
Joel
http://search.cpan.org/dist/App-perlbrew/lib/App/perlbrew.pm is easy and painless. You should not really rely on the _system_ Perl for your code, anyway :)
mfontani
always localize changes to `$_`
Eric Strom
If you use `map` instead of `do`, you'll localize the change to $_ and won't need to make the initial assignment: `job( map { s/find/replace/g; $_ } fetch() )`.
FM
A: 
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() );
Eric Strom