In Python and Ruby, a negative subscript indexes backward from the end of the array. That is, when the subscript is negative, the array length is added to it.
This is not the case in Lua. A negative subscript has no special meaning; it simply references or creates a table entry with that negative number as the key.
Python 2.7.3:
>>> a = [ 'x', 'y', 'z' ]
>>> a
['x', 'y', 'z']
>>> a[-1]
'z'
>>> a[-1] = 'm'
>>> a
['x', 'y', 'm']
>>>
Ruby 1.9.3:
irb(main):001:0> a = [ 'x', 'y', 'z' ]
=> ["x", "y", "z"]
irb(main):002:0> a
=> ["x", "y", "z"]
irb(main):003:0> a[-1]
=> "z"
irb(main):004:0> a[-1] = 'm'
=> "m"
irb(main):005:0> a
=> ["x", "y", "m"]
irb(main):006:0>
Lua 5.2.3:
> a = { 'x', 'y', 'z' }
> for key, value in pairs(a) do print( key, value ) end
1 x
2 y
3 z
> print( a[3] )
z
> print( a[-1] )
nil
> a[-1] = 'm'
> print( a[-1] )
m
> for key, value in pairs(a) do print( key, value ) end
1 x
2 y
3 z
-1 m
>
JavaScript's behavior is fairly similar to Lua's. You can use a negative subscript on an array, and in fact you can use any arbitrary string as a subscript. A JavaScript array is actually an object with some additional methods, properties (.length
) and behavior (updating .length
as needed). When you use array[-1]
you're adding or referencing a property with the key "-1"
, and .length
is not updated.
Chrome 33:
> var a = [ 'x', 'y', 'z' ];
undefined
> a
["x", "y", "z"]
> a[2]
"z"
> a[-1]
undefined
> a[-1] = 'm'
"m"
> a[-1]
"m"
> a[2]
"z"
> a
["x", "y", "z"]
> for( var key in a ) console.log( key, a[key] );
0 x
1 y
2 z
-1 m
undefined
Don't be misled by the undefined
printed at the end - that's not part of the for( var key in a )
enumeration, it's just printed there because console.log()
is the last expression evaluated in the loop and it does not return a value (it just prints a value).