Sub returning reference

T

Tony Muler

Hi there,

the following method (shortened for this post) looks
strange to me.

-- Code Start --
package DataFile;
# ....
sub get_data {
# Read data from a delimited file in an array or arrays
# (in which $data[a][x] means the value x in line a.

my $self = shift;
my $file = $self->{file};
my $i = 0; # Line count
my @row = ();
my @data = ();
open F, "<$file" || die "Cannot open $file. $!";
while (<F>) {
my @row = split (/-delimiter-/);
$data[$i++] = \@row; # $data[$i++]=@row not ok. Why?
# QUESTION TO C.L.P.M. ^^^^
}
return (\@data);
}

package test;
$obj = new DataFile;
$content = $obj->get_data();
print $content->[2]->[3]; # As an example. Ok.
-- Code End --

Isn't it strange to create my @data in the method and
return a reference to it. Ok, it stays alive because
something is pointing to it (right?), but isn't that
bad style?

Couldn't I build an array (instead arrayref) of
arrays (instead of arrayrefs) and return this,
so data would be called like
print $content[2][3];
Or am I totally confused now? Are arrays of arrays
always just arrays of array references?

Thank you for any recommendations or style comments.

T.
 
T

Tore Aursand

[...]
Isn't it strange to create my @data in the method and
return a reference to it.

Not at all. It's _good_ style, because you don't have to pass that,
possibly, huge amount of data around all the time.

Consider this snippet of code;

my @numbers = foo();

sub foo {
my @array = ();

for ( 1..10_000_000 ) {
push( @array, $_ );
}

return @array;
}

Both @array and @numbers would be quite huge, and when calling the
subroutine, the contents of @array would be copied to @numbers.

With references, ie. 'return \@array', only the _reference to_ the array
(ie. '@array') will be returned.
 
A

Anno Siegel

Tony Muler said:
Hi there,

the following method (shortened for this post) looks
strange to me.

-- Code Start --
package DataFile;
# ....
sub get_data {
# Read data from a delimited file in an array or arrays
# (in which $data[a][x] means the value x in line a.

my $self = shift;
my $file = $self->{file};
my $i = 0; # Line count

You don't need the line count. If you did, you could use $.
my @row = ();
my @data = ();
open F, "<$file" || die "Cannot open $file. $!";
while (<F>) {
my @row = split (/-delimiter-/);
$data[$i++] = \@row; # $data[$i++]=@row not ok. Why?
# QUESTION TO C.L.P.M. ^^^^

The last two lines are better written as

push @data, [ split /-delimiter-/ ];
}
return (\@data);
}

package test;
$obj = new DataFile;
$content = $obj->get_data();
print $content->[2]->[3]; # As an example. Ok.
-- Code End --

Isn't it strange to create my @data in the method and
return a reference to it. Ok, it stays alive because
something is pointing to it (right?), but isn't that
bad style?

Not at all, it's standard and considered good practice.
Couldn't I build an array (instead arrayref)

You *are* building an array. You are returning a reference to the
array you built. You could also return the array itself, at some
cost.
of
arrays (instead of arrayrefs) and return this,

No. "Arrays of arrays" in the true sense don't exist in Perl. The
values in arrays (and hashes) are always scalars, never aggregates,
so you must store references.
so data would be called like
print $content[2][3];

You can, syntactic sugar makes it so. But that's an abbreviation for
the explicit "$content->[2]->[3]".
Or am I totally confused now? Are arrays of arrays
always just arrays of array references?

Indeed. Same as in C, by the way, and some other languages.
Thank you for any recommendations or style comments.

See perlref, perlreftut and perldsc.

Anno
 
T

Tony Muler

Thank you both for your help; for confirming
that my estimations were not so wrong and my code
was not soooo bad.


Anno said:
You don't need the line count. If you did, you could use $.

Aha. Perl and its useful special variables. Didn't know this one.
( Ok, perldoc perlvar )
my @row = split (/-delimiter-/);
$data[$i++] = \@row; # $data[$i++]=@row not ok. Why?
The last two lines are better written as

push @data, [ split /-delimiter-/ ];

Perfect. I like that.

T.
 
L

Lukas Mai

Anno Siegel said:
Tony Muler said:
so data would be called like
print $content[2][3];
You can, syntactic sugar makes it so. But that's an abbreviation for
the explicit "$content->[2]->[3]".

No, the arrow is optional between bracket subscripts, so
$content[2][3] is the same as $content[2]->[3] or ${$content[2]}[3].
It accesses the third element of @content.
$content->[2]->[3] is the same as $content->[2][3] or
${${$content}[2]}[3] and treats $content as an array reference.

HTH, Lukas
 
G

Gunnar Strand

Lukas said:
Anno Siegel said:
Tony Muler said:
so data would be called like
print $content[2][3];

You can, syntactic sugar makes it so. But that's an abbreviation for
the explicit "$content->[2]->[3]".


No, the arrow is optional between bracket subscripts, so
$content[2][3] is the same as $content[2]->[3] or ${$content[2]}[3].
It accesses the third element of @content.
$content->[2]->[3] is the same as $content->[2][3] or
${${$content}[2]}[3] and treats $content as an array reference.

And, for completeness sake, it can also be written as $$content[2][3].

Kind Regards, /Gunnar
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top