Хук вызывается при изменении переменной - PullRequest
2 голосов
/ 14 января 2012

Был ли обработчик в ruby, который вызывается каждый раз, когда изменяется значение определенной переменной?

Ответы [ 2 ]

3 голосов
/ 14 января 2012

Если вы пишете расширение C для Ruby, вы можете создать глобальную переменную, которая запускает перехватчик всякий раз, когда кто-то его устанавливает.

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

Лучшей стратегией было бы сделать так, чтобы переменная читалась и устанавливалась с помощью соответствующих методов.Затем, когда вызывается метод setter, вы можете делать все, что захотите.Вот пример, который инкапсулирует переменную внутри объекта:

class Foo
  def bar=(v)
    @bar = v
    # do some stuff
  end

  def bar
    @bar
  end
end

Аналогично вы можете инкапсулировать переменную в модуле или классе вместо объекта.

1 голос
/ 14 января 2012

Преамбула: я это не решение (pst уже писал: его нет), но, возможно, это может помочь в особых ситуациях.

Моей первой идеей было использование freeze для получения решения:

a = "aa"
a.freeze
a << 'b'  #can't modify frozen string (RuntimeError)

Теперь мы должны переопределить freeze, и мы получим подсказку, когда переменная изменит значение:

module FreezeWarning
  def freeze
    puts "#{self}: I am changed"
  end
end

a = "aa"
a.extend(FreezeWarning)
a.freeze
a << 'b'  #aa: I am changed

Первая проблема: Нет способа получить имя переменной .

Вы можете решить эту проблему с помощью дополнительной переменной (Вы можете определить свою собственную идентификацию переменной, это не должно быть имя)

module FreezeWarning
  def change_warning(name)
    @varname = name
    self.freeze
  end
  def freeze
    puts "<#{@varname}> (#{self}): I am changed"
  end
end

a = "aa"
a.extend(FreezeWarning)
a.change_warning('a')
a << 'b'  #<a> (aa): I am changed

Но большая проблема: это работает только с изменениями значения, а не с новыми назначениями:

a = 5
a.freeze
a = 4
p a  # -> 4

Так что это только очень ограниченное «решение».

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