Discussion:
return the list content
Ken Peng
2014-08-18 08:17:53 UTC
Permalink
Hello,

sub myfunc {
my @x=(1,2,3);
return \@x;
}

# or,

sub myfunc {
my @x=(1,2,3);
return [@x];
}

which one is the better way to return the list content? And if the
method is an instance method?

Thanks.
--
To unsubscribe, e-mail: beginners-***@perl.org
For additional commands, e-mail: beginners-***@perl.org
http://learn.perl.org/
Paul Johnson
2014-08-18 08:38:30 UTC
Permalink
Post by Ken Peng
Hello,
sub myfunc {
}
# or,
sub myfunc {
}
which one is the better way to return the list content? And if the
method is an instance method?
Functionally, the two are identical. The first is returning a reference
to the array you have created. The second is returning a reference to a
new array created from a (shallow) copy of the array you have created.

The fist is to be preferred in my opinion, because it does exactly what
you want. The second does extra work and might cause someone to wonder
why you haven't just returned a reference to the array.

The second version is necessary when the array might persist between
subroutine calls and you effectively need to return a copy.
--
Paul Johnson - ***@pjcj.net
http://www.pjcj.net
--
To unsubscribe, e-mail: beginners-***@perl.org
For additional commands, e-mail: beginners-***@perl.org
http://learn.perl.org/
John SJ Anderson
2014-08-18 13:07:59 UTC
Permalink
Post by Paul Johnson
Post by Ken Peng
which one is the better way to return the list content? And if the
method is an instance method?
Functionally, the two are identical. The first is returning a reference
to the array you have created. The second is returning a reference to a
new array created from a (shallow) copy of the array you have created.
[ snip ]

To expand further (because you asked about "list context"), note that
both are returning a _scalar_, because references are always scalars.
If you want to return a list, you should just do

return @x;

If you wanted the return value to depend on the calling context, you
could use 'wantarray' like so:

return wantarray ? @x : \@x;

That said, APIs that have contextually dependent return values are
usually fairly confusing to use, so consider not doing this.

chrs,
john.
--
To unsubscribe, e-mail: beginners-***@perl.org
For additional commands, e-mail: beginners-***@perl.org
http://learn.perl.org/
Shawn H Corey
2014-08-18 12:08:33 UTC
Permalink
On Mon, 18 Aug 2014 16:17:53 +0800
Post by Ken Peng
sub myfunc {
}
# or,
sub myfunc {
}
# or

sub myfunc {
return [ 1, 2, 3 ];
}
--
Don't stop where the ink does.
Shawn
--
To unsubscribe, e-mail: beginners-***@perl.org
For additional commands, e-mail: beginners-***@perl.org
http://learn.perl.org/
lee
2014-09-08 22:13:13 UTC
Permalink
Post by Shawn H Corey
On Mon, 18 Aug 2014 16:17:53 +0800
Post by Ken Peng
sub myfunc {
}
# or,
sub myfunc {
}
# or
sub myfunc {
return [ 1, 2, 3 ];
}
Is there a difference to

sub myfunc {
return ( 1, 2, 3 );
}

? And my understanding was/is that in

sub myfunc {
my @x=(1,2,3);
return \@x;
}

a reference would be returned to an array that ceases to exist when the
function returning it has finished. At the point the function returns
to, there isn't anything left the reference could refer to.

Or is there?
--
Knowledge is volatile and fluid. Software is power.
--
To unsubscribe, e-mail: beginners-***@perl.org
For additional commands, e-mail: beginners-***@perl.org
http://learn.perl.org/
Jim Gibson
2014-09-08 22:24:56 UTC
Permalink
Post by lee
Post by Shawn H Corey
On Mon, 18 Aug 2014 16:17:53 +0800
Post by Ken Peng
sub myfunc {
}
# or,
sub myfunc {
}
# or
sub myfunc {
return [ 1, 2, 3 ];
}
Is there a difference to
sub myfunc {
return ( 1, 2, 3 );
}
The first example returns [ 1, 2, 3 ], which is a reference to a list with 3 elements. References are scalars.

The second example returns ( 1, 2, 3 ), which is a list with 3 elements.

So, yes, there is a difference.
Post by lee
? And my understanding was/is that in
sub myfunc {
}
a reference would be returned to an array that ceases to exist when the
function returning it has finished. At the point the function returns
to, there isn't anything left the reference could refer to.
Or is there?
Perl will not garbage-collect an element if there is a reference to it. So while the array name @x no longer is in scope once the subroutine has returned, the list that was the value of @x still exists in memory, and the reference returned by the subroutine will be valid.

If the reference is not saved or copied, then the list will eventually get garbage collected.
--
To unsubscribe, e-mail: beginners-***@perl.org
For additional commands, e-mail: beginners-***@perl.org
http://learn.perl.org/
lee
2014-09-09 21:09:52 UTC
Permalink
Post by Jim Gibson
Post by lee
Post by Shawn H Corey
On Mon, 18 Aug 2014 16:17:53 +0800
# or
sub myfunc {
return [ 1, 2, 3 ];
}
Is there a difference to
sub myfunc {
return ( 1, 2, 3 );
}
The first example returns [ 1, 2, 3 ], which is a reference to a list with 3 elements. References are scalars.
The second example returns ( 1, 2, 3 ), which is a list with 3 elements.
So, yes, there is a difference.
Hm, so what way of thinking is behind this, and how do you declare an
array?


my $i = 1;
my $f = 2.5;
my $s = 'string';
my $list = (1, 2, 3);
my $list_reference = [(1, 2, 3)];
my $dereferenced_list = $@list_reference;
my @artificial_array = $@list_reference;
my @true_array = ?


I'm finding this very confusing. What's the benefit of using extra
designators for some types of variables (arrays) while not even having
any at all for some others (lists)?
Post by Jim Gibson
Post by lee
? And my understanding was/is that in
sub myfunc {
}
a reference would be returned to an array that ceases to exist when the
function returning it has finished. At the point the function returns
to, there isn't anything left the reference could refer to.
Or is there?
Perl will not garbage-collect an element if there is a reference to
exists in memory, and the reference returned by the subroutine will be
valid.
If the reference is not saved or copied, then the list will eventually get garbage collected.
Hmm, ok, strange ... good to know, though.
--
Knowledge is volatile and fluid. Software is power.
--
To unsubscribe, e-mail: beginners-***@perl.org
For additional commands, e-mail: beginners-***@perl.org
http://learn.perl.org/
Shawn H Corey
2014-09-09 21:57:05 UTC
Permalink
On Tue, 09 Sep 2014 23:09:52 +0200
Post by lee
my $i = 1;
my $f = 2.5;
my $s = 'string';
my $list = (1, 2, 3);
No, the count of items in the list gets stored in $list: $list == 3
Post by lee
my $list_reference = [(1, 2, 3)];
I'm finding this very confusing. What's the benefit of using extra
designators for some types of variables (arrays) while not even having
any at all for some others (lists)?
Lists are sequences used by Perl. They are very short lived, seldom
longer than one statement.

An array is memory. It may be named, like `@array`
or anonymous, `[ 1, 2, 3 ]`

BTW, another way to dereference a array reference is:

my @array = @{ $list_reference };

but most people don't want to type the extra characters.
--
Don't stop where the ink does.
Shawn
--
To unsubscribe, e-mail: beginners-***@perl.org
For additional commands, e-mail: beginners-***@perl.org
http://learn.perl.org/
John SJ Anderson
2014-09-09 22:01:04 UTC
Permalink
Post by Shawn H Corey
Lists are sequences used by Perl. They are very short lived, seldom
longer than one statement.
The way I've always liked to explain this is that arrays are the
containers you use to store a list.

As Shawn says, a list is usually pretty ephemeral -- but if you want
it to stick around, you can put it in an array variable.

chrs,
john.
--
To unsubscribe, e-mail: beginners-***@perl.org
For additional commands, e-mail: beginners-***@perl.org
http://learn.perl.org/
Uri Guttman
2014-09-09 22:35:50 UTC
Permalink
Post by John SJ Anderson
Post by Shawn H Corey
Lists are sequences used by Perl. They are very short lived, seldom
longer than one statement.
The way I've always liked to explain this is that arrays are the
containers you use to store a list.
As Shawn says, a list is usually pretty ephemeral -- but if you want
it to stick around, you can put it in an array variable.
to be a little more exact, lists live only in expressions and are on the
stack. arrays can live between statements and are allocated from the heap.

also the names of those variables are confusing. artificial array?

uri
--
To unsubscribe, e-mail: beginners-***@perl.org
For additional commands, e-mail: beginners-***@perl.org
http://learn.perl.org/
Jim Gibson
2014-09-09 22:12:00 UTC
Permalink
Post by Shawn H Corey
On Tue, 09 Sep 2014 23:09:52 +0200
Post by lee
my $i = 1;
my $f = 2.5;
my $s = 'string';
my $list = (1, 2, 3);
No, the count of items in the list gets stored in $list: $list == 3
Unless the thing on the right-hand-side of the assignment is a 'list' and not an 'array'. This is the one place I can think of where the distinction between 'list' and 'array' actually makes a difference.

Compare this:

my $n = ( 4, 5, 6 );

with this:

my @a = ( 4, 5, 6 );
my $n = @a;

(Don't try this with the list ( 1, 2, 3 ), either!)
--
To unsubscribe, e-mail: beginners-***@perl.org
For additional commands, e-mail: beginners-***@perl.org
http://learn.perl.org/
Paul Johnson
2014-09-09 23:51:03 UTC
Permalink
Post by Jim Gibson
Post by Shawn H Corey
On Tue, 09 Sep 2014 23:09:52 +0200
Post by lee
my $i = 1;
my $f = 2.5;
my $s = 'string';
my $list = (1, 2, 3);
No, the count of items in the list gets stored in $list: $list == 3
Unless the thing on the right-hand-side of the assignment is a 'list' and not an 'array'. This is the one place I can think of where the distinction between 'list' and 'array' actually makes a difference.
my $n = ( 4, 5, 6 );
(Don't try this with the list ( 1, 2, 3 ), either!)
There's a little bit of confusion here. When you write
Post by Jim Gibson
Post by Shawn H Corey
Post by lee
my $list = (1, 2, 3);
there isn't actually a list anywhere in that statement, appearances to
the contrary notwithstanding.

To understand what is happening, notice first that the assignment is to
a scalar (confusingly named $list in this case). That means that the
assignment is in scalar context and so the expression (1, 2, 3) is
evaluated in scalar context.

In scalar context the parentheses () are used for controlling
precedence. The values 1, 2 and 3 are just scalar values. And the
commas are comma operators in scalar context.

In scalar context the comma operator evaluates its left-hand side,
throws it away and returns the right-hand side.

This means that the value of (1, 2, 3) in scalar context is 3, and this
is what gets assigned to $list.

What is not happening at all is the creation of a list of numbers and a
calculation of its length.

See also perldoc -q 'difference between a list and an array'
--
Paul Johnson - ***@pjcj.net
http://www.pjcj.net
--
To unsubscribe, e-mail: beginners-***@perl.org
For additional commands, e-mail: beginners-***@perl.org
http://learn.perl.org/
Jim Gibson
2014-09-09 22:05:58 UTC
Permalink
Post by lee
Post by Jim Gibson
Post by lee
Post by Shawn H Corey
On Mon, 18 Aug 2014 16:17:53 +0800
# or
sub myfunc {
return [ 1, 2, 3 ];
}
Is there a difference to
sub myfunc {
return ( 1, 2, 3 );
}
The first example returns [ 1, 2, 3 ], which is a reference to a list with 3 elements. References are scalars.
The second example returns ( 1, 2, 3 ), which is a list with 3 elements.
So, yes, there is a difference.
Hm, so what way of thinking is behind this, and how do you declare an
array?
Perls 1-4 (I believe) did not have references. They were added with Perl 5, which allowed complex data structures not possible without them. Think array of arrays and hashes of hashes. Once references were introduced, a lot of new possibilities for passing arguments and returning values arose.
Post by lee
my $i = 1;
my $f = 2.5;
my $s = 'string';
my $list = (1, 2, 3);
That should be: my @list = ( 1, 2, 3 );

Some people make a distinction between 'list' and 'array'. A list is a sequence of scalar values indexed by an integer. An array is a variable whose value is a list (or something like that -- I don't really distinguish the two myself.)
Post by lee
my $list_reference = [(1, 2, 3)];
That can be expressed more simply: my $list_reference = [ 1, 2, 3 ];
That is incorrect. You probably mean either this:

my @dereferenced_list = @$list_reference;

or this:

my $list_reference = \@list;

or even this:

my $list_reference = \(1, 2, 3);
Post by lee
I'm finding this very confusing. What's the benefit of using extra
designators for some types of variables (arrays) while not even having
any at all for some others (lists)?
The designators are for named variables. Lists are like pure values, just like 1.0 and "string", Like all literal values, they do not need designators (names).
Post by lee
Post by Jim Gibson
Perl will not garbage-collect an element if there is a reference to
exists in memory, and the reference returned by the subroutine will be
valid.
If the reference is not saved or copied, then the list will eventually get garbage collected.
Hmm, ok, strange ... good to know, though.
Not strange at all. If Perl knows there is no way to reference or access a value in memory, that value will get garbage collected. If there is a way, it won't. To do otherwise would either 1) leak memory, or 2) lead to invalid references.
--
To unsubscribe, e-mail: beginners-***@perl.org
For additional commands, e-mail: beginners-***@perl.org
http://learn.perl.org/
Shawn H Corey
2014-09-09 23:02:15 UTC
Permalink
On Tue, 9 Sep 2014 15:05:58 -0700
Post by Jim Gibson
Some people make a distinction between 'list' and 'array'. A list is
a sequence of scalar values indexed by an integer. An array is a
variable whose value is a list (or something like that -- I don't
really distinguish the two myself.)
A list can also be stored in a hash:

my %h = ( 'a', 1, 'b', 2, 'c', 3 );

Though, most times, people use the fat-comma notation:

my %h = ( a => 1, b => 2, c => 3 );


On Tue, 09 Sep 2014 18:35:50 -0400
Post by Jim Gibson
to be a little more exact, lists live only in expressions and are on
the stack. arrays can live between statements and are allocated from
the heap.
That isn't much help since the Perl documentation does not mention the
calling stack or the heap (except `perldoc perlguts`, of course). And
Perl switches between lists and arrays very casually. For example, when
calling a sub you give it a list of arguments:

foo( 1, 2, 3 );

But Perl stores them in an array:

sub foo {
my ( $x, $y, $z ) = @_;

And the same thing happens with a return:

return ( $x, $y, $z );

my @a = foo();
--
Don't stop where the ink does.
Shawn
--
To unsubscribe, e-mail: beginners-***@perl.org
For additional commands, e-mail: beginners-***@perl.org
http://learn.perl.org/
Shawn H Corey
2014-09-08 22:30:48 UTC
Permalink
On Tue, 09 Sep 2014 00:13:13 +0200
Post by lee
Post by Shawn H Corey
On Mon, 18 Aug 2014 16:17:53 +0800
Post by Ken Peng
sub myfunc {
}
# or,
sub myfunc {
}
# or
sub myfunc {
return [ 1, 2, 3 ];
}
This returns a reference to an anonymous array.
Post by lee
Is there a difference to
sub myfunc {
return ( 1, 2, 3 );
}
This returns a list, which can be stored in an array.
Post by lee
? And my understanding was/is that in
sub myfunc {
}
a reference would be returned to an array that ceases to exist when
the function returning it has finished. At the point the function
returns to, there isn't anything left the reference could refer to.
Or is there?
The reference to the array is returned. Perl keeps a reference count on
all the values. With the above return, you create two references to the
value in array @x. When @x goes out of scope, the reference count is
decreased by one. Since it's not zero, the values are returned to the
calling sub.
--
Don't stop where the ink does.
Shawn
--
To unsubscribe, e-mail: beginners-***@perl.org
For additional commands, e-mail: beginners-***@perl.org
http://learn.perl.org/
Rob Dixon
2014-09-09 01:12:45 UTC
Permalink
Post by Ken Peng
sub myfunc {
}
# or,
sub myfunc {
}
which one is the better way to return the list content? And if the
method is an instance method?
The first version of the subroutine is the best choice in the code shown
because it is less wasteful and has no external effect. It simply
creates an array, populates it, and returns a reference to that array.

The second option creates the same array and populates it, but then
copies it to another anonymous array, deletes the first array, and
returns a reference to the copy.

The big difference that is being missed so far is that, if the array was
static in some way, then returning a reference to it is very different
from returning a reference to a copy.

Consider this, where array @xx continues to exist and keeps its values
across calls to either subroutine

my @xx = ( 1, 2, 3 );

sub mysub1 {
\@xx;
}

sub mysub2 {
[ @xx ];
}

Now mysub1 will supply a reference to @xx itself, while mysub2 gives a
reference to a snapshot of @xx at the time of the call. Which of these
is best depends entirely on your purpose.

None of this seems relevant to your question about an instance method,
which in general will reflect the current state of the object. If you
explain the behaviour of the object better than we can help you more.

HTH,

Rob




---
This email is free from viruses and malware because avast! Antivirus protection is active.
http://www.avast.com
--
To unsubscribe, e-mail: beginners-***@perl.org
For additional commands, e-mail: beginners-***@perl.org
http://learn.perl.org/
Ken Peng
2014-09-09 01:20:44 UTC
Permalink
Since this is a shadow copy, I don't think the first array will be
deleted completely. Isn't it?
Post by Rob Dixon
The second option creates the same array and populates it, but then
copies it to another anonymous array, deletes the first array, and
returns a reference to the copy.
--
To unsubscribe, e-mail: beginners-***@perl.org
For additional commands, e-mail: beginners-***@perl.org
http://learn.perl.org/
Rob Dixon
2014-09-10 11:18:06 UTC
Permalink
Post by Ken Peng
Post by Rob Dixon
The second option creates the same array and populates it, but then
copies it to another anonymous array, deletes the first array, and
returns a reference to the copy.
Since this is a shadow copy, I don't think the first array will be
deleted completely. Isn't it?
The second option is this

sub myfunc {
my @x=(1,2,3);
return [@x];
}

And yes, the array @x is created, populated, and deleted completely
every time the subroutine is called.

In the first option

sub myfunc {
my @x=(1,2,3);
return \@x;
}

the array isn't deleted as long as the reference returned by the
subroutine is held somewhere, but as all references to it are gone it
too will be deleted.

Rob


---
This email is free from viruses and malware because avast! Antivirus protection is active.
http://www.avast.com
--
To unsubscribe, e-mail: beginners-***@perl.org
For additional commands, e-mail: beginners-***@perl.org
http://learn.perl.org/
Charles DeRykus
2014-09-13 03:40:41 UTC
Permalink
Post by Rob Dixon
Post by Ken Peng
Post by Rob Dixon
The second option creates the same array and populates it, but then
copies it to another anonymous array, deletes the first array, and
returns a reference to the copy.
Since this is a shadow copy, I don't think the first array will be
deleted completely. Isn't it?
The second option is this
sub myfunc {
}
every time the subroutine is called.
Hm, I believe you're in error IIRC. What happens is perl's internal array
structure for @x is marked inaccessible when the sub exits.This enables
the struct to be more quickly resurrected on subsequent calls. Scope is
preserved without doing extra work on re-entry.

Note the IIRC. Corrections welcome.
--
Charles DeRykus
--
To unsubscribe, e-mail: beginners-***@perl.org
For additional commands, e-mail: beginners-***@perl.org
http://learn.perl.org/
Loading...