Different array length depending on whether it is returned from a subroutine

P

paulburton0

This script is for a very basic web api client that I'm making. The server returns json and I'm using JSON:XS to decode that to native perl data structures. My problem is that I'm having trouble with an array that I'm returning from a subroutine. If I do not return the array (or arrayref), I can print all the elements of the array using foreach. If I *do* return the array (or arrayref), only one element is added to the array. See annotated code below. (Unfortunately, this code won't run as-is because API access requiresOAuth details that I can't share.) I'm hoping that there's an idiosyncrasyin perl (or huge stupid mistake that I'm not seeing) that someone can point out just looking at the code. I've seen similar questions asked elsewhere, but there's never a satisfactory answer (if any).

[... head of script snipped (oauth details, module declarations, etc.) ...]
sub fetch_likes{

my $offset = shift;

my $r;

if ($offset){

$r = $ua->get("http://api.tumblr.com/v2/user/likes?limit=20&offset=$offset");

}else{

$r = $ua->get("http://api.tumblr.com/v2/user/likes?limit=20");
}

my $response = $r->content();

my $json = JSON::XS->new->decode ($response);

my $likes = ${$json}{'response'}{'liked_posts'};

return $likes; # This is an arrayref
}

sub get_image_urls{

# This function expects a reference to an array containing liked posts.
# Such a reference is returned from fetch_likes()

my $likes = shift;

foreach (@$likes) {

my $photos = ${$_}{'photos'};

my @urls; # This initializes the array that I want to return.

foreach (@$photos){

push (@urls, ${$_}{'original_size'}{'url'}); # Populate the array
}

foreach (@urls){ # This prints every element in the array (20 or so),
print; # but *only* of the 'return' line below is commented
print"\n";
}

return \@urls; # Return the array reference. If this is uncommented,
# the foreach immediately above it will only output one
# array element. Behavior is the same if it's not a
# reference
}
}

# Main

my $ref_to_likes = fetch_likes();
my $ref_to_urls = get_image_urls($ref_to_likes);

foreach (@$ref_to_urls){ # This block behaves exactly like the one in
# the get_image_urls sub, depending on whether
# the return of that sub is commented or not.
print;
print "\n";
}
 
R

Rainer Weikusat

(e-mail address removed) writes:

[...]
my $likes = ${$json}{'response'}{'liked_posts'};

A general remark: Perl has (meanwhile and since a while) a
dereferencing operator. And the {} automatically quote arguments which
are 'simple idenifiers'. Considering both, the line above could be
written as

my $likes = $json->{response}{liked_posts}

eliminating some of the 'line noise' characters.
sub get_image_urls{

# This function expects a reference to an array containing liked posts.
# Such a reference is returned from fetch_likes()

my $likes = shift;

foreach (@$likes) {

my $photos = ${$_}{'photos'};

my @urls; # This initializes the array that I want to return.

foreach (@$photos){

push (@urls, ${$_}{'original_size'}{'url'}); # Populate the array
}

foreach (@urls){ # This prints every element in the array (20 or so),
print; # but *only* of the 'return' line below is commented
print"\n";
}

return \@urls; # Return the array reference. If this is uncommented,
# the foreach immediately above it will only output one
# array element. Behavior is the same if it's not a
# reference
}
}

You didn't per chance mean to place the return \@urls after the outer
foreach loop? With the code as it is quoted here, only the first
element in @$likes will ever be processed because the subroutine
returns at the end of the first iteration of the outer loop.
 
P

Paul Burton

You didn't per chance mean to place the return \@urls after the outer

foreach loop? With the code as it is quoted here, only the first

element in @$likes will ever be processed because the subroutine

returns at the end of the first iteration of the outer loop.

That was it. I just lost track of curly braces I guess. Thanks a lot for the second pair of eyes on this. And thanks to everyone who replied for the stylistic/practical tips as well.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,754
Messages
2,569,527
Members
44,998
Latest member
MarissaEub

Latest Threads

Top