2012-04-15 9 views
0

Mögliche Duplizieren:
Array slicing in Ruby: looking for explanation for illogical behaviour (taken from Rubykoans.com)Ruby-Arrays in Scheiben schneiden, kann nicht diese einfache Code-Schnipsel verstehen

Ich habe ein einfaches Array Objekt:

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

Seine Länge ist , klar, 4!

Nun nehmen, einen Blick auf diese Aussagen:

array[4,0] == [] 
array[5,0] == nil 

das Array Slicing vom 4. Index, ist es ein leeres Array zurückgibt, sondern vom 5. Element starten, gibt es gleich Null. Warum passiert das?

+0

gefunden die Antwort, danke! Aber ich mag es nicht :) –

Antwort

1

slice(start, length) (was die Methode aufgerufen wird, wenn man array[] zuzugreifen) gibt einen Array von Länge length bei Index beginnend start. Dies erklärt, warum array[4,0] zurückgeben [].

Es gibt jedoch einen Eckfall in dieser Methode. The Ruby documentation of slice sagt:

Gibt Null zurück, wenn der Index (oder Startindex) außerhalb des Bereichs liegen.

In Ihrem zweiten Beispiel 5 ist für array außerhalb des zulässigen Bereichs. Dies führt dazu, dass die Methode nil zurückgibt.

+1

Ja, aber 4 ist auch außerhalb des Bereichs. Liege ich falsch? –

1

Für eine Sekunde dachte ich, Sie hätten einen Fehler gefunden, aber ich denke, ich kann dieses Verhalten erklären. Der Startindex, den Sie slice geben, wird nur als vor das Element bei diesem Index betrachtet. So wird Index 4 als sehr Ende des Arrays (kurz vor Index 4, direkt nach Index 3) betrachtet. Die folgenden Beispiele sollen deutlich machen:

> [1,2,3,4][0, 3] 
# => [1, 2, 3] 
> [1,2,3,4][1, 3] 
# => [2, 3, 4] 
> [1,2,3,4][2, 3] 
# => [3, 4] 
> [1,2,3,4][3, 3] 
# => [4] 
> [1,2,3,4][4, 3] 
# => [] 
> [1,2,3,4][5, 3] 
# => nil 
1

Eigentlich ist der Grund für Dinge gefunden Sie „seltsam“ sollte immer liegen im Quellcode. Ich nehme nur die relevanten Ausschnitt aus https://github.com/ruby/ruby/blob/trunk/range.c

... 
if (beg < 0) { 
beg += len; 
if (beg < 0) 
    goto out_of_range; 
} 
if (err == 0 || err == 2) { 
if (beg > len) 
    goto out_of_range; 
if (end > len) 
    end = len; 
} 
... 

Wenn hier Index begonnen beg kleiner als -länge ist, gibt sie sich außerhalb der Reichweite Qnil. Andernfalls, wenn der Startindex größer als die Länge des Arrays ist (len im Code-Snippet), wird auch außerhalb des Bereichs (Qnil) zurückgegeben. HINWEIS hier, es ist größer als nicht größer oder gleich, deshalb erhalten Sie [] für array[4,0] (obwohl 4 ist außerhalb des Bereichs) aber nil für array[5,0]

Verwandte Themen