I just discovered the following odd behavior with String#split:
"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 from 2.0.0) is over 200 lines long and contains a passage like this:
/* L 5909 */
else if (rb_enc_asciicompat(enc2) == 1) {
if (RSTRING_LEN(spat) == 1 && RSTRING_PTR(spat)[0] == ' '){
split_type = awk;
}
}
Later, in the code for the awk split type, the actual argument isn't even used any more and does the same as a plain split.
- Does anyone else feel that this is somehow broken?
- Are there good reasons for this?
- Does “magic” like that happen more often than most people might think in Ruby?
It's consistent with Perl's split() behavior. Which in turn is based on Gnu awk's split(). So it's a long-standing tradition with origins in Unix.
From the perldoc on split:
As another special case, split emulates the default behavior of the command line tool awk when the PATTERN is either omitted or a literal string composed of a single space character (such as ' ' or "\x20" , but not e.g. / / ). In this case, any leading whitespace in EXPR is removed before splitting occurs, and the PATTERN is instead treated as if it were /\s+/ ; in particular, this means that any contiguous whitespace (not just a single space character) is used as a separator. However, this special treatment can be avoided by specifying the pattern / / instead of the string " " , thereby allowing only a single space character to be a separator.
Check out the documentation, this part in particular:
If pattern is a String, then its contents are used as the delimiter when splitting str. If pattern is a single space, str is split on whitespace, with leading whitespace and runs of contiguous whitespace characters ignored.
If pattern is omitted, the value of $; is used. If $; is nil (which is the default), str is split on whitespace as if ` ‘ were specified.
You can use a regexp to split the string.
来源:https://stackoverflow.com/questions/16301372/why-is-split-trying-to-be-too-smart