array[index,length] strange behaviour

Discussion in 'Ruby' started by Mikel Lindsaar, Sep 13, 2010.

  1. Hi all,

    Running Ruby 1.8.7. And I saw Jim Weirich's post about the Ruby Koans, =
    and I thought, what the hey! Lets do them!

    So I downloaded, and what do you know! I found something I didn't =
    understand!! :)

    Anyway, per http://ruby-doc.org/core/classes/Array.html#M002205 it says: =
    "Returns nil if the index (or starting index) are out of range".

    So given array:

    array =3D [:peanut, :butter, :and, :jelly]

    One would expect:

    array[4] =3D=3D nil #=3D> true
    array[5] =3D=3D nil #=3D> true

    Which works, 4 and 5 are both out of range.

    However:

    array[4,0] =3D=3D nil #=3D> false
    array[5,0] =3D=3D nil #=3D> true

    Huh? In actual fact array[4,0] returns an empty array. This seems in =
    conflict with the docs.

    Can someone more enlightened please explain?

    Thank you!

    Mikel
     
    Mikel Lindsaar, Sep 13, 2010
    #1
    1. Advertising

  2. On Sep 12, 2010, at 10:55 PM, Mikel Lindsaar wrote:

    > Hi all,
    >
    > Running Ruby 1.8.7. And I saw Jim Weirich's post about the Ruby
    > Koans, and I thought, what the hey! Lets do them!
    >
    > So I downloaded, and what do you know! I found something I didn't
    > understand!! :)
    >
    > Anyway, per http://ruby-doc.org/core/classes/Array.html#M002205 it
    > says: "Returns nil if the index (or starting index) are out of
    > range".
    >
    > So given array:
    >
    > array = [:peanut, :butter, :and, :jelly]
    >
    > One would expect:
    >
    > array[4] == nil #=> true
    > array[5] == nil #=> true
    >
    > Which works, 4 and 5 are both out of range.
    >
    > However:
    >
    > array[4,0] == nil #=> false
    > array[5,0] == nil #=> true
    >
    > Huh? In actual fact array[4,0] returns an empty array. This seems
    > in conflict with the docs.
    >
    > Can someone more enlightened please explain?
    >
    > Thank you!
    >
    > Mikel


    Well, the docs seem to describe the behavior properly. You have to
    read them closely when it says "equal to the array size..." but
    Programming Ruby (1.8 and 1.9) have essentially the same text.

    Here's a way I've thought about it:

    Picture the array with the comma after each element:

    [ :peanut, :butter, :and, :jelly, ]

    Then the first index is how many commas to skip before starting. So 4
    puts your mental cursor after the :jelly, but before the ]

    [ :peanut, :butter, :and, :jelly, ]
    ^
    Then you're still "in" the array and take as many elements as
    possible. Since there aren't any more, array[4,0] == array[4,1000] == []

    When trying to find the starting point for array[5,n], there's no 5th
    comma before the ] that ends the array. So you get nil.

    It helps me so I hope this description helps you, too!

    -Rob

    Rob Biedenharn
    http://AgileConsultingLLC.com/
    http://GaslightSoftware.com/
     
    Rob Biedenharn, Sep 13, 2010
    #2
    1. Advertising

  3. [Note: parts of this message were removed to make it a legal post.]

    On Mon, Sep 13, 2010 at 3:55 AM, Mikel Lindsaar <> wrote:

    > ... Anyway, per http://ruby-doc.org/core/classes/Array.html#M002205 it
    > says: "Returns nil if the index (or starting index) are out of range".
    > So given array:
    > array = [:peanut, :butter, :and, :jelly]
    > One would expect:
    > array[4] == nil #=> true
    > array[5] == nil #=> true
    > Which works, 4 and 5 are both out of range.
    > However:
    > array[4,0] == nil #=> false
    > array[5,0] == nil #=> true
    > Huh? In actual fact array[4,0] returns an empty array. This seems in
    > conflict with the docs.
    > Can someone more enlightened please explain?
    >


    As well as Rob's reply there is this recent thread, which has an explanation
    from Matz:

    http://groups.google.com/group/comp.lang.ruby/browse_thread/thread/f09c65251c72ab6/9a125107e3186534

    extracts:
    http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/368268
    ... So, to summarize, when indexing a position beyond the length of a
    string, ruby returns nil. But when indexing a slice beyond the length
    of a string, ruby returns an empty string "" for the first index
    beyond and then nil.

    I don't like that this passes
    assert "foo"[3] != "foo"[3,1] ...

    http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/368271
    "foo"[3,1] is "" since when index is within the string, the sought
    length will be rounded to fit in the size. And 3 (which equals to the
    length of the string) is considered as touching the end of the string,
    so the result length is zero. ... matz.

    On Mon, Sep 13, 2010 at 4:22 AM, Rob Biedenharn
    <>wrote:

    > ... Here's a way I've thought about it:
    > Picture the array with the comma after each element ...


    That may - or may not! - explain this behaviour: I've been wondering why the
    statements with 1 (but not 2) 'superfluous' commas at the end don't give a
    syntax error:
    arr = [] #=> []
    arr = [ 0 ] #=> [0]
    arr = [ 0, ] #=> [0]; superfluous comma is ignored
    arr = [ 0, 1, 2 ] #=> [0, 1, 2]
    arr = [ 0, 1, 2, ] #=> [0, 1, 2]; superfluous comma is ignored
    but these give: syntax error, unexpected ',', expecting ']'
    # arr = [ 0, 1, 2, 3,, ]
    # arr = [ , ]
     
    Colin Bartlett, Sep 13, 2010
    #3
  4. On Sep 13, 2010, at 1:47 PM, Colin Bartlett wrote:
    > On Mon, Sep 13, 2010 at 4:22 AM, Rob Biedenharn
    > <>wrote:
    >
    >> ... Here's a way I've thought about it:
    >> Picture the array with the comma after each element ...

    >
    > That may - or may not! - explain this behaviour: I've been wondering
    > why the
    > statements with 1 (but not 2) 'superfluous' commas at the end don't
    > give a
    > syntax error:
    > arr = [] #=> []
    > arr = [ 0 ] #=> [0]
    > arr = [ 0, ] #=> [0]; superfluous comma is ignored
    > arr = [ 0, 1, 2 ] #=> [0, 1, 2]
    > arr = [ 0, 1, 2, ] #=> [0, 1, 2]; superfluous comma is ignored
    > but these give: syntax error, unexpected ',', expecting ']'
    > # arr = [ 0, 1, 2, 3,, ]
    > # arr = [ , ]



    Well, given that Matz is a C programmer (as was I), he may have wanted
    to allow:

    <code lang="ruby">
    arr = [
    0,
    1,
    2,
    3,
    ]
    </code>

    When making C array literals, I would often do:

    <code lang="C">
    int arr[] = {
    0
    ,1
    ,2
    ,3
    };
    </code>

    because it was much more likely to add another element to the end than
    to the beginning of the array. In C, you couldn't have a trailing
    comma and in ruby, there has to be something to clue the parser into
    the fact that there's more to come on the next line.

    -Rob

    Rob Biedenharn
    http://AgileConsultingLLC.com/
    http://GaslightSoftware.com/
     
    Rob Biedenharn, Sep 13, 2010
    #4
  5. On Mon, Sep 13, 2010 at 10:47 AM, Colin Bartlett
    <> wrote:
    > On Mon, Sep 13, 2010 at 3:55 AM, Mikel Lindsaar <> wrot=

    e:
    >
    >> ... Anyway, per http://ruby-doc.org/core/classes/Array.html#M002205 it
    >> says: =C2=A0"Returns nil if the index (or starting index) are out of ran=

    ge".
    >> So given array:
    >> =C2=A0array =3D [:peanut, :butter, :and, :jelly]
    >> One would expect:
    >> =C2=A0array[4] =3D=3D nil #=3D> true
    >> =C2=A0array[5] =3D=3D nil #=3D> true
    >> Which works, 4 and 5 are both out of range.
    >> However:
    >> =C2=A0array[4,0] =3D=3D nil #=3D> false
    >> =C2=A0array[5,0] =3D=3D nil #=3D> true
    >> Huh? =C2=A0In actual fact array[4,0] returns an empty array. =C2=A0This =

    seems in
    >> conflict with the docs.
    >> Can someone more enlightened please explain?
    >>

    >
    > As well as Rob's reply there is this recent thread, which has an explanat=

    ion
    > from Matz:
    >
    > http://groups.google.com/group/comp.lang.ruby/browse_thread/thread/f09c65=

    251c72ab6/9a125107e3186534
    >
    > extracts:
    > http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/368268
    > ... So, to summarize, when indexing a position beyond the length of a
    > string, ruby returns nil. But when indexing a slice beyond the length
    > of a string, ruby returns an empty string "" for the first index
    > beyond and then nil.
    >
    > I don't like that this passes
    > assert "foo"[3] !=3D "foo"[3,1] ...


    Strings are weird because they act like a container where the
    individual contained items look like length 1 slices, which can create
    an expectation that indexing and length-1 slices with the same base
    index would be the identical. But the behavior makes sense when you
    think about slicing (as opposed to simple indexing) as an operation on
    a container that returns a container, while indexing is an operation
    on a container that returns an element.

    There's no reason to expect an equivalency between the element
    returned by container[3] indexing and the container returned by
    container[3,1] slicing. You should expect that the first element
    (index of 0) in the container returned by the slicing would be the
    same as the element returned by the indexing, and with Ruby's existing
    behavior for both Arrays and Strings where slicing out of range
    returns an empty container of the same kind you sliced, that works.

    container[3] =3D=3D container[3,1][0]

    whether container is "foo", [:f,:eek:,:eek:], "foobar", or [1,2,3,4,5]

    If Ruby returned nil rather than an empty container from slicing past
    the end of the container, than, for containers with length of 3 or
    less, the counter intuitive result would be:

    counter[3] !=3D container[3,1][0]
     
    Christopher Dicely, Sep 13, 2010
    #5
  6. Mikel Lindsaar, Sep 14, 2010
    #6
  7. On Mon, Sep 13, 2010 at 1:47 PM, Colin Bartlett <> wrote:
    > As well as Rob's reply there is this recent thread, which has an explanati> from Matz:
    >
    > http://groups.google.com/group/comp.lang.ruby/browse_thread/thread/f09c65251c72ab6/9a125107e3186534
    >


    Which includes this gem:

    "And a tip for you; never mention PoLS again to persuade me. It's no
    use. If you have real trouble besides misunderstanding, let me know.
    matz. "

    I've long felt that the problem with the principle of least surprise
    is that what's surprising is inherently subjective. One man's obvious
    is another's surprise.

    --
    Rick DeNatale

    Blog: http://talklikeaduck.denhaven2.com/
    Github: http://github.com/rubyredrick
    Twitter: @RickDeNatale
    WWR: http://www.workingwithrails.com/person/9021-rick-denatale
    LinkedIn: http://www.linkedin.com/in/rickdenatale
     
    Rick DeNatale, Sep 14, 2010
    #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. ton
    Replies:
    4
    Views:
    1,033
  2. Shawn W_
    Replies:
    5
    Views:
    284
    Aldric Giacomoni
    Sep 16, 2009
  3. Tom
    Replies:
    3
    Views:
    213
    salsablr
    Dec 20, 2004
  4. Tuan  Bui
    Replies:
    14
    Views:
    476
    it_says_BALLS_on_your forehead
    Jul 29, 2005
  5. Tomasz Chmielewski

    sorting index-15, index-9, index-110 "the human way"?

    Tomasz Chmielewski, Mar 4, 2008, in forum: Perl Misc
    Replies:
    4
    Views:
    298
    Tomasz Chmielewski
    Mar 4, 2008
Loading...

Share This Page