Разделение массива Ruby ActiveSupport против разделения строки

"abc def ".split(" ")

возвращается

["abc", "def"]

Таким образом, я ожидал:

["a", "b", "c", " ", "d", "e", "f", " "].split(" ")

вернуться

[["a", "b", "c"], ["d", "e", "f"]]

но он вернулся

[["a", "b", "c"], ["d", "e", "f"], []]

Я прочитал исходный код, выполняя разделение в active_support/core_ext/array/grouping.rb (я использую ActiveSupport 4.0.0 с ruby ​​2.0.0-p247). Вы можете найти 2 строки документа здесь: http://api.rubyonrails.org/classes/Array.html#method-i-split и код выглядит следующим образом:

def split(value = nil, &block)
    inject([[]]) do |results, element|
      if block && block.call(element) || value == element
        results << []
      else
        results.last << element
      end

      results
    end
  end

Это объясняет, как происходит расщепление.

Итак, это предполагаемое поведение или это ошибка ActiveSupport?


person Nicolas M.    schedule 07.11.2013    source источник
comment
Программное обеспечение будет работать точно так, как оно закодировано, но может работать не так, как задумано. Вы никогда не сможете сказать, является ли определенное поведение ошибкой или спецификацией, взглянув на код, но, возможно, сможете определить это, прочитав спецификации.   -  person sawa    schedule 07.11.2013
comment
Добавил ссылку на документ. Приведенные здесь примеры не охватывают этот пограничный случай.   -  person Nicolas M.    schedule 07.11.2013


Ответы (1)


Вероятно, это предполагаемое поведение, а не ошибка. Согласно документации, разделение массива:

Делит массив на один или несколько подмассивов на основе значения-разделителя или результата необязательного блока.

Это не дает никаких гарантий относительно смежных или ведущих пробелов.

С другой стороны, документация ядра Ruby для String#split состояний:

Если шаблон является строкой, то ее содержимое используется в качестве разделителя при разбиении строки. Если шаблон представляет собой один пробел, строка str разбивается на пробелы, при этом начальные пробелы и ряды смежных пробельных символов игнорируются.

Как видите, ожидаемое поведение работает только с пробелами, а не с любой строкой.

 "abc ccc def ".split("c")
 => ["ab", " ", "", "", " def "]

При разбиении массива понятие «пробел» больше не имеет смысла. Поэтому я думаю, что такое поведение разумно, хотя поначалу, возможно, и противоречит здравому смыслу.

person davogones    schedule 07.11.2013