Добавление метода в класс Array через proc / block?

Я пытаюсь добавить дополнительную функциональность в класс Array, чтобы принять блок. Я думаю, что в основном у меня это получилось, однако я не уверен в синтаксисе, который я хочу использовать, когда вызов метода использует приведение .to_proc / & для предопределенных методов (например, .odd?).

У меня такой код:

class Array 

  def keep
    each do |user_array_element|
      user_array_element
      if yield(user_array_element) == true 
        kept_elements ||= []
        kept_elements << user_array_element
      end
    end
  end
end

Пытаемся пройти следующий тест:

assert_equal [1, 3], [1, 2, 3].keep(&:odd?)

person Tony DiNitto    schedule 20.04.2015    source источник
comment
Вы можете захотеть, чтобы keep возвращал перечислитель, если блок не задан, чтобы его можно было связать в цепочку.   -  person Cary Swoveland    schedule 20.04.2015


Ответы (2)


Ваш тест не проходит, потому что each возвращает перечислимое значение, к которому он был вызван. Чтобы исправить это, измените свое определение следующим образом:

class Array 
  def keep
    [].tap do |kept_elements|
      self.each do |element|
        kept_elements << element if (yield(element) == true)
      end
    end # will return kept_elements
  end
end

Альтернативой является использование each_with_object:

class Array 
  def keep
    self.each_with_object([]) do |element, kept_elements|           
      kept_elements << element if (yield(element) == true)
    end # will return kept_elements
  end
end

Приведенный выше код просто показывает, как заставить работать ваш собственный код. Но по сути, вы пишете метод для того, что уже делает select (за исключением того, что он выбирает любой элемент, для которого блок не дает nil или false).

person SHS    schedule 20.04.2015

Ваш метод keep должен возвращать массив, содержащий сохраненные элементы. Я немного изменил ваш код, это должно сработать:

class Array 
  def keep
    kept_elements = []
    each do |user_array_element|
      if yield(user_array_element) == true 
        kept_elements << user_array_element
      end
    end
    kept_elements
  end
end
person Yu Hao    schedule 20.04.2015