FSEvents in MacRuby: wrong callback is executed-Collection of common programming errors

Yeah, this is really weird. I also have this behavior. It seems like the latest registered callback always gets called. But on the bright side, it is possible, from the fourth argument to the callback, to get the path to the directory that actually got called. I had to use a construct like this.

I’m not much of a rubyist, but this code works for me.

framework 'Cocoa'
framework 'CoreServices'


class Monitor
  @@registry = {}
  def self.register(dir, other_data)
    @@registry[dir] = other_data
  end

  def initialize(dir, other_data)
      @dir = dir

      self.class.register(dir, other_data)
      callback = Proc.new do |stream, context, count, paths, flags, ids|
          paths.cast!('*')

          p "the callback that triggered has closure variable @dir=#{@dir}"
          p "but the actual callback said the dir was #{paths[0]}"
          p "the metadata that I stored associated with that directory is #{@@registry[paths[0]]}"
      end


      @stream = FSEventStreamCreate(KCFAllocatorDefault, callback, nil, [@dir], KFSEventStreamEventIdSinceNow, 0.0, 0)
      FSEventStreamScheduleWithRunLoop(@stream, CFRunLoopGetCurrent(), KCFRunLoopDefaultMode)
      FSEventStreamStart(@stream)
  end
end

Monitor.new(Dir.pwd + "/dir1/", 'dir1 data')
Monitor.new(Dir.pwd + "/dir2/", 'dir2 data')
Monitor.new(Dir.pwd + "/dir3/", 'dir3 data')

app = NSApplication.sharedApplication
app.run

Here’s the output I see:

rmcgibbo@Roberts-MacBook-Pro-2 ~/local/fsync
$ macruby fsevents.rb &
[1] 14638

rmcgibbo@Roberts-MacBook-Pro-2 ~/local/fsync
$ touch dir1/mao

rmcgibbo@Roberts-MacBook-Pro-2 ~/local/fsync
$ "the callback that triggered has closure variable @dir=/Users/rmcgibbo/local/fsync/dir3/"
"but the actual callback said the dir was /Users/rmcgibbo/local/fsync/dir1/"
"the metadata that I stored associated with that directory is dir1 data"