Ruby块作用域 - 如何调用实例方法

时间:2014-01-28 13:28:29

标签: ruby scope block fssm

我在Ruby中使用块时遇到了一些麻烦。我创建了一个使用fssm gem监视目录的类。当发生变化时,我想通知观察者。我正在使用Observable模块。

代码:

require 'fssm'
require 'observer'

class FSSM_Spike
include Observable

def initialize watcher
    add_observer watcher
    FSSM.monitor('./temp/', '**/*', :directories => true) do
        update do |base, relative|
            puts 'update'
            notify_observers(self, 'update')
        end
        delete do |base, relative|
            puts 'delete'
            notify_observers(self, 'delete')
        end
        create do |base, relative|
            puts 'create'
            notify_observers(self, 'create')
        end
    end
end
end

任何想要创建FSSM_Spike实例的观察者都必须将它们传递给new。然后将这些添加到列表观察者中。但是,当发生FSSM回调时,notifiy_observers方法是未知的,因为该上下文中的self是FSSM :: Path。

我尝试向FSSM_Spike添加另一个方法,看看我是否可以调用它,但结果相同。

如何在块上下文中调用方法?

2 个答案:

答案 0 :(得分:2)

def initialize watcher
  # ⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓
  this_observer = self
  …
  create do |base, relative|
    puts 'create'  # ⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓
    notify_observers(this_observer, 'create')
  end
end
如果我正确地理解你想要实现什么,那么

应该可以做到。

答案 1 :(得分:0)

您可以将self的当前值保存在变量中,然后将其传递给块:

require 'fssm'
require 'observer'

class FSSM_Spike
include Observable

def initialize watcher
    current_object = self # save reference to the current object

    add_observer watcher
    FSSM.monitor('./temp/', '**/*', :directories => true) do
        update do |base, relative|
            puts 'update'
            current_object.notify_observers(current_object, 'update')
        end
        delete do |base, relative|
            puts 'delete'
            current_object.notify_observers(current_object, 'delete')
        end
        create do |base, relative|
            puts 'create'
            current_object.notify_observers(current_object, 'create')
        end
    end
end
end