Anonymous

D

David Frauzel

Quick (or maybe not) question.

What is the difference between an anonymous array, an array, and a list?

For instance, here I have a list:

print +('foo', 'bar')[0];

And here I have an array constructed using a list:

@foo = ('foo', 'bar');

Given the flexibility of those two options, when (or why) must I use an
anonymous array? (Or is the answer, "only when you need to construct a
reference to one".)

My hunch is that it has to do with THING-of-THING structures (perldsc),
since,

@foo = ('foo', ('bar', 'baz'));

just created a single flat array with 3 elements. But, then, we're back to
references. So are references really the only use for anonymous
constructors at all...?
 
T

Tad McClellan

David Frauzel said:
What is the difference between an anonymous array, an array, and a list?


The difference between an anonymous array and an array is that
one has a name and one doesn't.

The difference between a list and an array is given in the answer
to that Frequently Asked Question, and since you have surely
already seen that answer I will not attempt to repeat it here.

For instance, here I have a list:

print +('foo', 'bar')[0];

And here I have an array constructed using a list:

@foo = ('foo', 'bar');

Given the flexibility of those two options, when (or why) must I use an
anonymous array?


You never _must_ use an array without a name, but it is often
convenient, particularly if you do not need to make use of
the name.

(Or is the answer, "only when you need to construct a
reference to one".)


That is when it is convenient, but you can always construct a
reference to a named array just as well...

My hunch is that it has to do with THING-of-THING structures (perldsc),
^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^

Those are most commonly called "multi level data structures".

since,

@foo = ('foo', ('bar', 'baz'));

just created a single flat array with 3 elements. But, then, we're back to
references. So are references really the only use for anonymous
constructors at all...?


If it has no name, then a reference is the only way to access it, so: yes.
 
D

David Frauzel

You never _must_ use an array without a name, but it is often
convenient, particularly if you do not need to make use of
the name.

Thanks. :) One follow-up question:

These two statements have different behavior:

@foo = @bar;
@foo = ['foo', 'bar'];

The second statement returns a reference, not a copy. Is this intentional,
as another kind of convenience? (Since returning a copy of it would just be
wasteful.) And what happens to @foo when the anonymous array goes out of
scope? (Presumably at the end of the current block?)
 
E

Eric Schwartz

David Frauzel said:
These two statements have different behavior:

@foo = @bar;
@foo = ['foo', 'bar'];

The second statement returns a reference, not a copy. Is this intentional,
as another kind of convenience?

It's intentional, because that's what [ list ] does-- return a
reference. If you want @foo to be ('foo', 'bar'), then you should
assign that to it, not ['foo', 'bar']. See perlreftut for more info on
references.
(Since returning a copy of it would just be wasteful.)

Not if that's what you needed, which is why you have both () and [].
And what happens to @foo when the anonymous array goes out of scope?

Nothing, presuming that @foo has wider scope than that. $foo[0] will
still contain a reference to an anonymous array.

-=Eric
 
B

Ben Morrow

Quoth David Frauzel said:
You never _must_ use an array without a name, but it is often
convenient, particularly if you do not need to make use of
the name.

Thanks. :) One follow-up question:

These two statements have different behavior:

@foo = @bar;
@foo = ['foo', 'bar'];

Note that this sets $foo[0] to the reference. This is not at all the
same as

@foo = ('foo', 'bar');
The second statement returns a reference, not a copy. Is this intentional,
as another kind of convenience? (Since returning a copy of it would just be
wasteful.)

No, it is intentional as that is what you asked for. Compare:

my $foo = ['foo', 'bar'];
my @foo = ('foo', 'bar');
And what happens to @foo when the anonymous array goes out of
scope? (Presumably at the end of the current block?)

You are confusing a variable and its name. A name has a scope; the
variable itself is refcounted. The variable is not destroyed until all
refs and all names are gone. So:


{
my $foo;
{
my $bar = [];
$foo = [];
}
# The name $bar goes out of scope here.
# The scalar variable it refers to is destroyed, as there are no
# other refs.
# The anon array it held a reference to is destroyed, as it has no
# name and no refs.

# The name $foo is still in scope, so the variable still exists.
# The scalar named by $foo contains a reference to an anon array, so
# that anon array still exists, as well.
}
# The name $foo goes out of scope here. The scalar variable and anon
# array are destroyed as for $bar.

Does this make things clearer?

Ben
 
D

David Frauzel

Does this make things clearer?

Ah, reference counting. That makes more sense, yes. No need to worry about
dereferencing something that no longer exists.

Except now I'm again uncertain about anonymous array. :p

Is this:

['foo', 'bar']

An anonymous array, or a *reference* to an anonymous array? (Which is what
I meant originally about anonymous arrays and references being
inseperable.)

I get the feeling now that there's no such thing as "just" an anonymous
array, only references to them.

What I mean is:

# Passes an array (as a list)
&foo @bar;
# Passes a list
&foo +('foo', 'bar');
# Passes a reference
&foo ['foo', 'bar'];

So "anonymous" doesn't just mean unnamed, it also implicates a reference?
(But I get the idea they wouldn't be possible otherwise.)
 
B

Ben Morrow

Quoth David Frauzel said:
Is this:

['foo', 'bar']

An anonymous array, or a *reference* to an anonymous array? (Which is what
I meant originally about anonymous arrays and references being
inseperable.)

It returns a reference to one.
I get the feeling now that there's no such thing as "just" an anonymous
array, only references to them.

Well, yes... for the array to exist, it must *either* have at least one
name *or* at least one reference... Think about it. An anon array has no
name: how are you going to access it except through a reference?
What I mean is:

# Passes an array (as a list)
&foo @bar;
# Passes a list
&foo +('foo', 'bar');
# Passes a reference
&foo ['foo', 'bar'];

Yup.

Two notes: don't call subs with & unless you know what it does and why
you need it, and you can just write

foo 'foo', 'bar';

rather than that +(...) business.

Ben
 
D

David Frauzel

Yup.

Two notes: don't call subs with & unless you know what it does and why
you need it, and you can just write

foo 'foo', 'bar';

rather than that +(...) business.

Just being overtly clear that those were subs, and just using +() to
indicate overtly that I meant a list (since foo may not have been a list
operator).

Thanks for the answers. :}
 
L

Lukas Mai

David Frauzel schrob:
[...]
What I mean is:
# Passes an array (as a list)
&foo @bar;

That's a syntax error:
Array found where operator expected at -e line 1, near "&foo "
# Passes a list
&foo +('foo', 'bar');

No. It's parsed as &foo + ('???', 'bar'), i.e. it calls foo with the
current @_ and adds 'bar' to the result.
# Passes a reference
&foo ['foo', 'bar'];

syntax error at -e line 1, near "&foo ["

foo(['foo', 'bar']) (or foo ['foo', 'bar'] if sub foo is predeclared) on
the other hand calls foo with a one-element list. That element is an
array reference.

Conclusion: Don't use & for sub calls unless you know *exactly* what
you're doing. And subs are always called with an argument list (which
may be empty or contain references).
So "anonymous" doesn't just mean unnamed, it also implicates a reference?
(But I get the idea they wouldn't be possible otherwise.)

Basically yes. You need either a name or a reference to use a variable.
Otherwise it's unreachable.

HTH, Lukas
 

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,776
Messages
2,569,603
Members
45,189
Latest member
CryptoTaxSoftware

Latest Threads

Top