Я узнаю о волшебстве Перечислимого в Ruby. Я слышал, что нужно просто включить Enumerable
и реализовать метод each
и может обладать полномочиями Enumerable для этого класса.реализовать `each` для перечислимого mixin в Ruby
Итак, я подумал о реализации моего собственного пользовательского класса Foo для практики. Это выглядит, как показано ниже:
class Foo
include Enumerable
def initialize numbers
@num = numbers
end
def each
return enum_for(:each) unless block_given?
@num.each { |i| yield i + 1 }
end
end
Этот класс принимает массив и его each
работает почти аналогична Array#each
. Вот разница:
>> f = Foo.new [1, 2, 3]
=> #<Foo:0x00000001632e40 @num=[1, 2, 3]>
>> f.each { |i| p i }
2
3
4
=> [1, 2, 3] # Why this? Why not [2, 3, 4]?
Все работает так, как я ожидаю, кроме одной вещи, которая является последним утверждением. Я знаю его возвращаемое значение, но не должно быть [2, 3, 4]
. Есть ли способ сделать это [2, 3, 4]
.
Также прокомментируйте, как я применил each
. Если есть лучший способ, дайте мне знать. Сначала в моей реализации у меня не было этой строки return enum_for(:each) unless block_given?
, а затем она не работала, когда не было выделено никаких блоков. Я заимствовал эту строку откуда-то, а также, пожалуйста, скажите мне, правильно ли это справиться с ситуацией или нет.
С 'yield (i + 1) if block_given?' Я получаю неправильный результат для f.each – Lokesh
@Lokesh, возможно, вы пропустили некоторый код. Пожалуйста, см. Текущую версию ответа – Ilya
Мне очень нравится ваше первое решение. Второе решение, которое вы предложили изменить для инициализации, не вписывается в мою потребность, потому что вместо (i + 1) у меня есть что-то вроде ('abc' * i), которое занимает пространство, поэтому изменение @num перед рукой будет на большее пространство, чем это необходимо. – Lokesh