简体   繁体   中英

Ruby block scope - how to call instance method

I'm having a bit of trouble with a block in Ruby. I've created a class which monitors a directory using the fssm gem. When a change occurs I want to notify observers. I'm using the Observable module.

Code:

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

Any observers which want to create an instance of FSSM_Spike must pass themselve to new. These then get added to the list observers. However, when a FSSM callback occurs, the method notifiy_observers is not known, as self in that context is FSSM::Path.

I tried adding another method to FSSM_Spike to see if I could call that but had the same result.

How can I call methods from within a block context?

def initialize watcher
  # ⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓
  this_observer = self
  …
  create do |base, relative|
    puts 'create'  # ⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓
    notify_observers(this_observer, 'create')
  end
end

should do the trick if I properly understood what do you want to achieve.

You can save the current value of self in a variable and pass it later to the block:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM