2013-04-30 3 views
6

私はちょうど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(2.0.0からstring.c)が200行以上の長さであり、このような流路を含んでいます。

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

その後、 awkスプリットタイプのコードでは、実際の引数はもはや使用されず、平文と同じになりますsplit

  • 他に誰かがこれが何とか壊れていると感じていますか?
  • これには十分な理由がありますか?
  • このような「魔法」は、ほとんどの人がRubyで考えるよりも頻繁に起こりますか?
+0

なぜ「賢すぎる」と記録されているのですか?これは、テキストの分割に使用する代替パターンを渡すことで選択した場合に上書きできる、意図したデフォルトの動作です。 –

+0

あまりにもスマートな私は、すべての空白文字で分割したいルビーの推測を意味します。ここでは、文字通りスペースで分割するように指示しています。 –

+0

私は、おそらくこの質問に対する一般的で満足のいく答えがないことを認識しているので、この質問を閉じるために投票するつもりです。すべてのあなたの答えとコメントありがとう! –

答えて

4

これは、Perlのsplit()の動作と一致しています。これは、Gnu awk'ssplit()に基づいています。だから、これはUnixの起源を持つ長年の伝統です。別の特別な場合として

、分割パターンが省略されているいずれかの コマンドラインツールのawkのデフォルトの動作またはシングルスペース文字で構成されるリテラル 文字列をエミュレート:perldocsplit上から

(例えば ''または '\ x20'、 などですが、/ /など)。この場合、EXPRの先頭の空白は、分割が発生する前に が削除され、パターンが/ \ s + /の場合は として扱われます。特に、これは、隣接するすべての空白(単一の空白文字だけではない)がセパレータとして使用されることを意味します。 しかし、この特殊な処理は、文字列 ""の代わりに パターンを指定することで避けることができるので、単一の スペース文字だけを区切り文字にすることができます。

+1

私はPerlの分割でちょっと遊びましたが、これは引数が必要なので、Perlではこれが実際に意味があることに気付きました。空の文字列は、別の特別なケースであるため動作しません(rubyのように文字の配列を返します)。 'split(undef、$ str)'だったのですが、 'split( ''、$ str)'とは異なり、 'split( ''、$ str)'のように動作します。私はそれがかなり一貫していないと思う:)。結局のところ、何がこのようなものなのか、そしてPerlのことはあまりにも頻繁に行われているので、私はここでやめます:) –

+0

あなたの答えはまだ最高ですので、私はそれを受け入れます。ありがとう! –

+0

興味深い歴史。 – davogones

2

特にこの部分、documentationをチェック:

パターンが文字列である場合は、STRを分割するときに、その内容がデリミタ として使用されます。 patternが単一のスペースである場合、strは の空白で分割され、先行する空白と連続した空白の実行は無視されます。 文字は無視されます。

パターンを省略すると、$;使用されている。もし$; (デフォルトでは )、strは ``が指定されているかのように空白で分割されます。

正規表現を使用して文字列を分割することができます。

+0

ありがとう!私はその文書を読んだ。私の質問は、「行ってこれを修正すべきか、これには正当な理由があるのでしょうか?」のようなものです。 –

+0

少なくとも、意図されていることはわかっています。 Matzが設計した理由を見つけようとすることができます。また、これが奇妙であると主張することもできます。しかし、あなたは "行くとそれを修正する"ことはできません。誰かがマッツです。 – sawa

+0

もちろん、MatzはMRIの未来について決めます。しかし、我々はまだ彼に改善の可能性を指摘することができる;) –