2013-04-30 11 views
6

ich gerade entdeckt, die folgende seltsame Verhalten mit String#split:Warum ist Split ('') versucht (zu) schlau zu sein?

"a\tb c\nd".split 
=> ["a", "b", "c", "d"] 

"a\tb c\nd".split(' ') 
=> ["a", "b", "c", "d"] 

"a\tb c\nd".split(/ /) 
=> ["a\tb", "c\nd"] 

The source (string.c von 2.0.0) über 200 Zeilen lang und enthält eine Passage wie folgt aus:

/* L 5909 */ 
else if (rb_enc_asciicompat(enc2) == 1) { 
    if (RSTRING_LEN(spat) == 1 && RSTRING_PTR(spat)[0] == ' '){ 
     split_type = awk; 
    } 
} 

Später in dem Code für die awk Split-Art, das eigentliche Argument wird nicht einmal mehr verwendet und tut das gleiche wie eine einfache split.

  • Hat sonst jemand das Gefühl, dass das irgendwie kaputt ist?
  • Gibt es gute Gründe dafür?
  • Passiert "Magie" öfter, als die meisten Leute in Ruby denken?
+0

Warum ist etwas dokumentiert, das "zu schlau" ist? Es handelt sich um ein beabsichtigtes Standardverhalten, das Sie überschreiben können, wenn Sie ein alternatives Muster zum Teilen von Text übergeben. –

+0

Mit zu klug meine ich ruby ​​rät, dass ich auf alle Leerzeichen Zeichen teilen möchte, wo ich buchstäblich sage es auf Räume zu teilen. –

+0

Ich werde dafür stimmen, diese Frage zu schließen, da mir klar wird, dass es wahrscheinlich keine allgemeine, befriedigende Antwort auf diese Frage gibt. Danke für all deine Antworten und Kommentare! –

Antwort

4

Es ist konsistent mit Perl split() Verhalten. Das wiederum basiert auf Gnu awk'ssplit(). Es hat also eine lange Tradition mit Ursprüngen in Unix.

Von dem perldoc auf split:

Als weiteren Sonderfall, Split emuliert das Standardverhalten des Kommandozeilen-Tool awk, wenn das Muster entweder weggelassen oder ein wörtlichen Zeichenfolge aus einem einzelnen Leerzeichen bestehen (wie zum Beispiel "oder" \ x20 ", , aber nicht zB//). In diesem Fall wird ein vorangestelltes Leerzeichen in EXPR entfernt, bevor das Teilen auftritt, und das Muster wird stattdessen als behandelt, wenn es/\ s +/wäre; Dies bedeutet insbesondere, dass alle zusammenhängenden Leerzeichen (nicht nur ein einzelnes Leerzeichen) als Trennzeichen verwendet werden. Diese spezielle Behandlung kann jedoch vermieden werden, indem das Muster 0/// anstelle der Zeichenfolge "" angegeben wird, wodurch nur ein einzelnes Leerzeichen als Trennzeichen verwendet werden kann.

+1

Ich spielte ein bisschen mit Perl's Split und bemerkte, dass dies in Perl eigentlich Sinn macht, da es ein Argument benötigt. Eine leere Zeichenfolge würde nicht funktionieren, da dies ein weiterer Spezialfall ist (gibt ein Array von Zeichen zurück, wie in Ruby). Der nächste Aufruf ohne Perl in Split war 'split (undef, $ str)', aber das verhält sich eigentlich wie 'split ('', $ str)', nicht wie 'split ('', $ str)' also Ich denke, es ist nicht ganz konsistent :). Immerhin streiten wir darüber, warum die Dinge so sind und das in Perl schon zu oft gemacht wurde, also höre ich hier auf :) –

+0

Ihre Antwort ist immer noch die beste, also akzeptiere ich sie. Vielen Dank! –

+0

Interessante Geschichte. – davogones

2

Schauen Sie sich die documentation, ist dieser Teil insbesondere:

Wenn Muster ein String ist, dann wird der Inhalt als Trennzeichen verwendet, wenn str splitten. Wenn Muster ein einzelnes Leerzeichen ist, wird str auf Leerzeichen aufgeteilt, wobei führende Leerzeichen und Zeichenfolgen mit zusammenhängenden Leerzeichen ignoriert werden.

Wenn Muster fehlt, ist der Wert von $; wird eingesetzt. Wenn $; ist null (das ist der Standardwert), str wird auf Whitespace aufgeteilt, als ob `'angegeben wurde.

Sie können eine Regexp verwenden, um die Zeichenfolge zu teilen.

+0

Danke! Ich habe die Dokumentation gelesen. Meine Frage ist eher wie "Sollten wir gehen und das reparieren, oder gibt es einen guten Grund dafür?" –

+0

Zumindest wissen wir, dass es beabsichtigt ist. Wir können versuchen, den Grund zu finden, warum Matz das so gemacht hat, und wir können auch behaupten, dass das merkwürdig ist. Aber Sie können nicht "gehen und es reparieren". Wer entscheidet, ist Matz. – sawa

+0

Natürlich entscheidet Matz über die Zukunft der MRT. Aber wir können immer noch einen Punkt auf mögliche Verbesserungen zu ihm gehen;) –

Verwandte Themen