Принимая объяснение документации ruby API для String # each_char , он предлагает получить строку при вызове этого метода вместе с данным блоком.
each_char {|cstr| block } → str
Но при выполнении этого в irb результат будет не таким, как ожидалось, и возвращается только строка, с которой мы начали.
irb(main):001:0> v = "foobar".each_char { |c| c + "." }
=> "foobar"
Проблема, которую это вызывает, состоит в том, что назначение этого вызова метода довольно обманчиво, поскольку оно не возвращает ожидаемый результат, а просто строку, с которой мы начали:
irb(main):002:0> puts v
foobar
=> nil
Использование инструкции break
- единственный способ вернуть значение из блока во время присвоения переменной.
irb(main):003:0> v = "foobar".each_char { |c| break c + "." }
=> "f."
Вопросы:
Почему методы, вызываемые с помощью блока, не возвращают вычисленные ими значения? Является ли это просто особым случаем с этой реализацией, поскольку я уверен, что Array # каждый возвращает новый массив. Но опять же, String # each_byte также ничего не возвращает. Что здесь происходит?
Какой самый элегантный способ присвоения обработанных значений из блока? Является ли обезьяна исправлениями вариант?
Дополнительная информация: я использую ruby 2.6.3
(Примечание: я видел [этот вопрос от Эда], но в 2017 году был сделан вывод, что использование оператор присваивания приводит к синтаксическим ошибкам, ruby явно не ведет себя так в случае Array#each
.)