obtaining lengths of slices

Discussion in 'Perl' started by Griff, Aug 4, 2004.

  1. Griff

    Griff Guest

    @array1 = (1,2,3);

    $length = @array1[1,2]; # assigning a slice to $length

    print "length = $length"; # prints 3 (ie length of array not length of slice)

    @slice = @array1[1,2];

    print "\n";

    $length = @slice; # assigning slice-converted-into-array to $length

    print "length = $length"; # prints 2

    ----------------------------------------

    Why the difference ?

    Advice welcomed.

    Thanks - Griff
     
    Griff, Aug 4, 2004
    #1
    1. Advertising

  2. Griff wrote:
    > @array1 = (1,2,3);
    >
    > $length = @array1[1,2]; # assigning a slice to $length
    >
    > print "length = $length"; # prints 3 (ie length of array not length of slice)
    >
    > @slice = @array1[1,2];
    >
    > print "\n";
    >
    > $length = @slice; # assigning slice-converted-into-array to $length
    >
    > print "length = $length"; # prints 2
    >
    > ----------------------------------------
    >
    > Why the difference ?


    Because an array slice is a LIST, not an array. A LIST returns the
    last element when evaluated in scalar context, as opposed to an array
    which returns the number of elements when evaluated in scalar context.

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
     
    Gunnar Hjalmarsson, Aug 4, 2004
    #2
    1. Advertising

  3. Griff

    Guest

    Gunnar Hjalmarsson <> wrote in message news:<Oj3Qc.99995$>...
    > Because an array slice is a LIST, not an array. A LIST returns the
    > last element when evaluated in scalar context, as opposed to an array
    > which returns the number of elements when evaluated in scalar context.


    There is no such thing in Perl as a LIST in a scalar context!

    A slice in a scalar context returns the last element.

    IMNSHO an array slice in an obviously scalar context should throw a
    warning. This would be much more use than the downright dumb "Scalar
    value @foo[1] better written as $foo[1]" warning we have now. I quite
    often want to use a slice that happens _now_ to be a single element
    slice but which earlier or later in the evolution of the code may have
    more elements. On the other hand can see no reason to ever
    intensionally use an array (or hash) slice in a context that is known
    at compile time to be scalar.

    (It can make sense to use a list slice in a scalar context. It also
    can make sense to use an array slice in a subroutine return where the
    context is not known until runtime.)

    This newsgroup does not exist (see FAQ). Please do not follow-up here
    without pointing this out.
     
    , Aug 4, 2004
    #3
  4. Griff

    Joe Smith Guest

    Griff wrote:

    > @array1 = (1,2,3);
    > $length = @array1[1,2]; # assigning a slice to $length
    > print "length = $length"; # prints 3 (ie length of array not length of slice)


    The number 3 is not what you think it is.

    @array1 = (10,20,30);
    $lastitem = @array1[1,2];
    print "Last item returned by the comma operator is: $lastitem\n";

    $length_of_slice = () = @array1[1,2];
    print "Using a dummy list returns the length of $length_of_slice\n";

    -Joe
     
    Joe Smith, Aug 4, 2004
    #4
  5. wrote:
    > Gunnar Hjalmarsson wrote:
    >> Because an array slice is a LIST, not an array. A LIST returns
    >> the last element when evaluated in scalar context, as opposed to
    >> an array which returns the number of elements when evaluated in
    >> scalar context.

    >
    > There is no such thing in Perl as a LIST in a scalar context!


    In that case, how would you describe this statement:

    my $scalar = (10, 20, 30);

    (It generates "Useless use ... in void context" warnings, but $scalar
    is assigned he value of the last element.)

    > A slice in a scalar context returns the last element.


    What's the difference compared to a list literal (besides the warnings)?

    > IMNSHO an array slice in an obviously scalar context should throw a
    > warning.


    Aha, so you want them to behave identically. ;-)

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
     
    Gunnar Hjalmarsson, Aug 4, 2004
    #5
  6. Griff

    Guest

    Gunnar Hjalmarsson <> wrote in message news:<jGaQc.7204$>...
    > wrote:
    > > Gunnar Hjalmarsson wrote:
    > >> Because an array slice is a LIST, not an array. A LIST returns
    > >> the last element when evaluated in scalar context, as opposed to
    > >> an array which returns the number of elements when evaluated in
    > >> scalar context.

    > >
    > > There is no such thing in Perl as a LIST in a scalar context!

    >
    > In that case, how would you describe this statement:
    >
    > my $scalar = (10, 20, 30);


    An obfucated way of saying:

    10; 20; my $scalar = 30;

    No, seriously, I might describe it as a list but I would know I was
    using sloppy terminology in the same way as a might sloppily refer to
    an "array of arrays" in Perl when really I mean "array of refernces to
    arrays". As I've said numerous times sloppy short-hand terminology is
    fine as long as everyone knows that's what it is. Things start to go
    wrong as soon as people start trying to draw inferences from a literal
    interpretation of the short-hand terminology.

    I certainly would not describe the RHS of the above statement as a
    LIST (in capitals) because it is not.

    I've previously suggested we could introduce the term "lexical list"
    to describe a fragment of Perl source code that has a list-like
    appearance but is not a LIST. The trouble with this is that people
    might confuse people even more.

    In perl there are two ways a comma can be parsed. In an argument-list
    (of a protyped function) list it can be parsed as an argument
    separator.

    In other contexts it's an left associative operator.

    In a LIST context comma is the LIST concatenation operator. It
    evaluates it's LHS and RHS operands in LIST contexts then returns the
    concatenation of the LISTs.

    In a SCALAR context comma evaluates it's LHS operand in a VOID
    context, then evaluates it's RHS operand in a SCALAR context then
    returns value of the RHS.

    In a VOID context comma evaluates it's LHS operand in a VOID context,
    then evaluates it's RHS operand in a VOID context then doesn't return
    anything (because it's in a VOID context - like duh!).

    Note unlike most operators the order of the evaluation of the operands
    by a comma operator in a SCALAR or VOID context is assured.
    Technically it's not assured in a LIST context but I suspect that it
    would break so much code it it ever changed that it's unlikely ever to
    do so.

    > > A slice in a scalar context returns the last element.

    >
    > What's the difference compared to a list literal (besides the warnings)?


    There is really no such thing as a list literal in Perl although it
    is a convenient short-hand to describe an expression consisting
    entirely of literals and comma operators evaluated in a LIST context.
    There certainly is no such thing as a list literal in a scalar
    context. There is such a thing as a slice in a scalar context.

    Let us consider the two facts in question here.

    A) scalar(1,2,3) same as scalar((1,2,3)[-1])
    B) scalar(@foo[EXPR]) same as scalar((@foo[EXPR])[-1])

    I'm not denying that there is a superficial similarity. However you
    appeared to claim a _causual_ relationship (A=>B). There is no such
    relationship. There is no general rule.

    It should also be noted that

    scalar(foo(),bar()) != scalar((foo(),bar())[-1])

    > > IMNSHO an array slice in an obviously scalar context should throw a
    > > warning.

    >
    > Aha, so you want them to behave identically. ;-)


    That has no meaning because the situations are not comparible.

    my $bar = @foo[3]; # Currently: warn, I want: warn
    my ($bar) = @foo[3]; # Currently: warn, I want: no warn
    my $bar = @foo[1,2]; # Currently: no warn, I want: warn
    my $bar = @foo[@q]; # Currently: no warn, I want: warn
     
    , Aug 5, 2004
    #6
  7. wrote:
    > Gunnar Hjalmarsson wrote:
    >> wrote:
    >>>There is no such thing in Perl as a LIST in a scalar context!

    >>
    >>In that case, how would you describe this statement:
    >>
    >> my $scalar = (10, 20, 30);

    >
    > An obfucated way of saying:
    >
    > 10; 20; my $scalar = 30;


    <interesting discussion snipped>

    Thanks for the lecture! :)

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
     
    Gunnar Hjalmarsson, Aug 6, 2004
    #7
    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. Taras_96

    Variable 'variable lengths'

    Taras_96, May 8, 2005, in forum: VHDL
    Replies:
    2
    Views:
    514
    Taras_96
    May 9, 2005
  2. Chris Schumacher

    string lengths as integers.

    Chris Schumacher, Nov 14, 2003, in forum: C++
    Replies:
    3
    Views:
    493
    Catalin Pitis
    Nov 14, 2003
  3. Grumfish
    Replies:
    2
    Views:
    384
    Bengt Richter
    Aug 19, 2003
  4. Replies:
    9
    Views:
    374
    Robert Kern
    May 13, 2005
  5. jt
    Replies:
    3
    Views:
    963
    Keith Thompson
    May 23, 2005
Loading...

Share This Page