2

I have been using Perl for a while but is bothered by one syntax problem. In some packages, a method can return an array. For example

$root->getlist();

Will return an array. Now I want to get the first element of the result. Of course I can do this:

my @results = $root->getlist();
if($results[0] =~ /wow/) {
    print "Qualified result";
}

However, this is very troublesome. Is there a way that I can combine the first line with second line? I tried this but failed.

if(${$root->getlist()}[0] =~ /wow/) {
    print "Qualified result";
}

Is there a way to do this quick?

A better example: Consider this following package:

package Try;

sub new {
    my $package = shift;
    return bless({}, $package);
}

sub getList {
    return (1,2,3,4,5);
}

1;

Now I have a user pl file like this:

use lib '.';
use Try;
use strict;

my $obj = Try->new();
print ($obj->getList())[0];

Trying to run this script will result in:

syntax error at perlarrayaccess.pl line 6, near ")["

Execution of perlarrayaccess.pl aborted due to compilation errors.

2
  • That syntax error is because the first open parenthesis is parsed as the parentheses surrounding the arguments to print. Try print $obj->getList()[0]; without the extra parenthesis and see if it works. Commented Sep 2, 2011 at 21:01
  • 2
    In addition to use strict, you should use warnings. If you did, you'd see that you are trying to call print as a function in the last example. Commented Sep 2, 2011 at 21:07

4 Answers 4

5
if ( ( $root->get_list() )[0] =~ /wow/ ) {
    print "Qualified result";
}
Sign up to request clarification or add additional context in comments.

3 Comments

Sorry it actually doesn't work. Like the sample code up there I just updated.
@pulseball, your example doesn't work because print is interpreted as a function call. use warnings to see what I mean. If you put it in the if block, like Chris, it will work... at least it did for me.
@gpojd Now I see. The () was interpreted as functions parenthesis. Lazy makes me scratch my head. lol.
2

There's wantarray for that. In your sub returning the array, do:

sub getlist()
{
    my $self = shift;

    #  caller wants the full list
    if (wantarray) {
        # fetch all
        return @all_results;
    } else {
        # fetch only first result here.
        return $one_result;
    }
}

This would save you the overhead of fetching all results, when only the one is required. If it's another index you specifically need, write:

if ([$root->getlist]->[5] =~ /wow/) {
...
}

I know, perl is not about easy reading, but this one's more legible than ${$root->get}[0].

2 Comments

You shouldn't need to make an array reference and dereference it to get fhe syntax right.
I agree with chris lutz, you can use chris J's method to pull one element, however I agree wholeheartedly that if there is to be nice behavior with one element AND different nice behavior for many elements, the onus can be on the sub to get it right. Especially if you are writing it.
0
if($root->getlist()[0] =~ /wow/) {
    print "Qualified result";
}

Ought to work. The second thing that you tried treats the returned value as an array reference and tries to dereference it. The method just returns an array (or rather, a list - there is a difference), so you need to just access the element you want.

3 Comments

It doesn't work either, like the example in the updated question.
Is it not working in my sample code (with no extraneous parenthesis inside an if statement) or in some other context (like your added example)?
No it gives error. Actually Linus Kleen's method and Chris J's methods both work.
0

Using Perl syntax you can just assign return value to a list of variables:

my ($result) = $root->getlist();
print "Qualified result" if $result =~ /wow/;

This is very basic Perl syntax that often used when you need to get few parameters in sub:

sub get_three_params {
    my ($foo, $bar, $baz) = @_;
}

1 Comment

This way requires two lines, which is not easier than what I mentioned. I want to access the returned value in one statement

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.