1

I have a function like

sub multi_return {
    my ($val1, $val2) = ('','');
    #does something
    return ($val1, $val2);
}

Is there a way I can concatenate both returned vales with different string variables without having to use temporary variables?

my $string1 = 'some text';
my $string2 = 'some other text';
my ($tmp1,tmp2) = multi_return();
$string1 .= $tmp1;
$string2 .= $tmp2
undef($tmp1);
undef($tmp2);

This does not work

($string1, $string2) = multi_return();

Edit:

More generally, I'm searching for a way to concatenate two lists of strings, where both lists have the same length. The strings on the same positions of each list should be concatenated.

I guess the second part of @amon's answer serves my purpose.

2
  • 2
    Perhaps you could explain what you are trying to achieve? I mean: what is the concatenation for? Perhaps instead of doing it that way, pass the strings to function and make the function return already concatenated elements? Commented Jun 20, 2013 at 10:51
  • Passing along strings to the function does not work everytime, as sometimes I need this to work with system functions. Commented Jun 20, 2013 at 11:40

3 Answers 3

4

What you ask is not generally possible. However, we can do some looping to abstract over the number of return values:

my @strings = ("some text", "some other text");
my @ret = multi_return;
$strings[$_] .= $ret[$_] for 0 .. $#strings;

We can write a sub that in turn abstracts over that:

sub append_all {
  my $suffixes = shift;
  $_ .= shift @$suffixes for @_; # uses aliasing behaviour to modify out-args
}

my $string1 = "some text";
my $string2 = "some other text";

append_all([multi_return()] => $string1, $string2);
Sign up to request clarification or add additional context in comments.

2 Comments

Using arrays (especially for the 'string' part') is not really helping me, as I cannot use variables with self-explaining names
I added another level of abstraction that might do what you want.
2

I think you are overthinking this. Why not just pass the strings to the subroutine, concatenate inside, and then assign them the return value? Like this:

my $str1 = "foo";
my $str2 = "bar";
my @args = qw(something else you need);

($str1, $str2) = multi_return($str1, $str2, @args);
# $str1 == "foosomething";
# $str2 == "barsomething else"

sub multi_return {
    my ($str1, $str2, @args) = @_;
    $str1 .= "something";
    $str2 .= "something else";
    .... # etc
    return ($str1, $str2);
}

On a related note, your code:

my $string1 = 'some text';
my $string2 = 'some other text';
my ($tmp1,tmp2) = multi_return();
$string1 .= $tmp1;
$string2 .= $tmp2
undef($tmp1);
undef($tmp2);

Is better written like this:

my $string1 = 'some text';
my $string2 = 'some other text';
{
    my ($tmp1, $tmp2) = multi_return();
    $string1 .= $tmp1;
    $string2 .= $tmp2;
}

Lexical variables are restricted to the scope where they are defined, in this case the surrounding block we placed around it. With your code, the variables $tmp1 and $tmp2 are still in scope, where they can possibly mess things up.

2 Comments

The first part of your answer is somehow identical to @amon's second part.
@Pit Are you accusing me of plagiarising amon's answer? They are similar in function, because that is the function you requested. They are quite different in implementation, and mine is IMO more readable, while amon's is more flexible.
-2

You can declare the temporary variables in a block so that they are not available to the rest of the block of code

my $string1 = 'some text';
my $string2 = 'some other text';
{
    my ($tmp1,tmp2) = multi_return();
    $string1 .= $tmp1;
    $string2 .= $tmp2
}

3 Comments

Please tell me how this is not the same as TLP's answer. The only difference is one space, one $, and one semicolon less, when compared with his last code example.
@amon There's also a missing dollar sign. :)
@amon TLP and I answered at about the same time. I apologise if TLP answered first and I missed what they wrote. As for the missing dollar, that is missing in the original question and in TLP's copy of it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.