Anonymous

Discussion in 'Perl Misc' started by David Frauzel, May 26, 2004.

  1. 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...?
    David Frauzel, May 26, 2004
    #1
    1. Advertising

  2. David Frauzel

    Uri Guttman Guest

    answer: anonymous

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
    Uri Guttman, May 26, 2004
    #2
    1. Advertising

  3. David Frauzel <> wrote:

    > 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.


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
    Tad McClellan, May 26, 2004
    #3
  4. Tad McClellan <> wrote in
    news::

    > 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?)
    David Frauzel, May 28, 2004
    #4
  5. David Frauzel <net.weathersongATnemo> writes:
    > 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
    --
    Come to think of it, there are already a million monkeys on a million
    typewriters, and Usenet is NOTHING like Shakespeare.
    -- Blair Houghton.
    Eric Schwartz, May 28, 2004
    #5
  6. David Frauzel

    Ben Morrow Guest

    Quoth David Frauzel <net.weathersongATnemo>:
    > Tad McClellan <> wrote in
    > news::
    >
    > > 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

    --
    It will be seen that the Erwhonians are a meek and long-suffering people,
    easily led by the nose, and quick to offer up common sense at the shrine of
    logic, when a philosopher convinces them that their institutions are not based
    on the strictest morality. [Samuel Butler, paraphrased]
    Ben Morrow, May 28, 2004
    #6
  7. Ben Morrow <> wrote in
    news:c96214$a0f$:

    > 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.)
    David Frauzel, May 28, 2004
    #7
  8. David Frauzel

    Ben Morrow Guest

    Quoth David Frauzel <net.weathersongATnemo>:
    > Ben Morrow <> wrote in
    > news:c96214$a0f$:
    >
    > 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

    --
    perl -e'print map {/.(.)/s} sort unpack "a2"x26, pack "N"x13,
    qw/1632265075 1651865445 1685354798 1696626283 1752131169 1769237618
    1801808488 1830841936 1886550130 1914728293 1936225377 1969451372
    2047502190/' #
    Ben Morrow, May 28, 2004
    #8
  9. Ben Morrow <> wrote in
    news:c96pa0$hlu$:

    > 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. :}
    David Frauzel, May 28, 2004
    #9
  10. David Frauzel

    Lukas Mai Guest

    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
    --
    #include <stdio.h>
    static int r(int c,int d){return d && d < 27 ? 96 & c | 1 + (12+d) % 26 : c;}
    static int o(int c){return c!=EOF ? putchar(r(c,64^c&223)),o(getchar()) : 0;}
    int main(void){return o(getchar());}
    Lukas Mai, May 28, 2004
    #10
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Casey
    Replies:
    3
    Views:
    843
    Casey
    Jan 30, 2004
  2. Replies:
    1
    Views:
    425
    Gunnar Hjalmarsson
    Feb 18, 2004
  3. Guenther Liebowitz
    Replies:
    3
    Views:
    333
    Guenther Liebowitz
    Aug 14, 2003
  4. Reporter
    Replies:
    3
    Views:
    462
    Mike Schilling
    May 12, 2007
  5. Replies:
    1
    Views:
    212
Loading...

Share This Page