Добавьте функцию обратного вызова в массив Ruby, чтобы что-то делать при добавлении элемента - PullRequest
2 голосов
/ 31 октября 2010

Я хотел бы добавить что-то вроде функции обратного вызова в массив Ruby, чтобы при добавлении элементов в этот массив вызывалась эта функция. Одна вещь, о которой я могу думать, это переопределить все методы (например,

Есть ли более простое решение?

Ответы [ 3 ]

6 голосов
/ 31 октября 2010

Следующий код вызывает хук size_changed только тогда, когда размер массива изменился и ему передан новый размер массива:

a = []

class << a
  Array.instance_methods(false).each do |meth|
    old = instance_method(meth)
    define_method(meth) do |*args, &block|
      old_size = size
      old.bind(self).call(*args, &block)
      size_changed(size) if old_size != size
    end if meth != :size
  end
end

def a.size_changed(a)
  puts "size change to: #{a}"
end

a.push(:a) #=> size change to 1
a.push(:b) #=> size change to 2
a.length 
a.sort!
a.delete(:a) #=> size change to 1
2 голосов
/ 31 октября 2010

Используйте шаблон "Наблюдатель", чтобы получать уведомления об изменениях размера массива, который вы хотите наблюдать: Ruby Observer Это избавляет вас от необходимости переопределять все методы, добавляющие элемент в массив

2 голосов
/ 31 октября 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...