LINUX.ORG.RU

[ruby][noob] Неожиданное поведение при сортировке


0

1

Доброго времени суток. Захотел отсортировать символы строки в алфавитном порядке — наткнулся вот на что:

irb(main):008:0> "foobar".respond_to? :sort
=> true
irb(main):009:0> "foobar".sort # WTF?
=> ["foobar"]
irb(main):010:0> "foobar".chars.to_a.sort.to_s # решил через жопу
=> "abfoor"

Интересует не столько правильное решение, сколько причина такого неожиданного поведения метода.

Может потому, что строка это строка а не массив, пока не вызван to_a?
// Руби не знаю.

jessey ()
Ответ на: комментарий от jessey

Может потому, что строка это строка а не массив, пока не вызван to_a?

Это очевидно. Но оставим пока этот вопрос.

Дело в том, что, в соответствии с принципом наименьшего удивления, пользователь, вызвав метод sort для однородной коллекции, может ожидать два возможных результата:

  • что-то типа «Unhandled exception: bla-bla-bla no such method», если такой метод отсутсвует
  • коллекцию, в которой будут находиться элементы исходной, отсортированные в определенном порядке (в данном случае в лексикографическом)

Но меньше всего я ожидал в ответ получить массив (!), хранящий исходную коллекцию.

theNamelessOne ★★★★★ ()
irb(main):001:0> "cdab".sort
NoMethodError: undefined method `sort' for "cdab":String
	from (irb):1
	from /usr/bin/irb:12:in `<main>'
irb(main):002:0> "cdab".respond_to? :sort
=> false

=)

anonymous ()
Ответ на: комментарий от O02eg

Returns an array containing the items in enum sorted, either according to their own <=> method, or by using the results of the supplied block

т.е. при попытке сортировки строки использовался этот метод, причем считалось, что строка содержит ровно один элемент — саму себя?

theNamelessOne ★★★★★ ()
Ответ на: комментарий от theNamelessOne

как видишь. Можешь дописать свой sort к строкам и пользовать его, если очень хочется. Вроде такого:

irb(main):001:0> "foo".sort
NoMethodError: undefined method `sort' for "foo":String
	from (irb):1
	from /usr/bin/irb:12:in `<main>'
irb(main):002:0> class String
irb(main):003:1> def sort
irb(main):004:2> self.chars.to_a.sort.join
irb(main):005:2> end
irb(main):006:1> end
=> nil
irb(main):007:0> "foobar".sort
=> "abfoor"
anonymous ()
Ответ на: комментарий от theNamelessOne

Скорее всего, по крайней мере, если передать sort'у блок, он не выполнялся.

O02eg ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.