rb-inotify (0.9.10)のコードリーディングをしました。listenで利用されているgemです。

inotifyはLinuxの機能になるのでLinuxでのみ動作します。macOSの場合はFSEventsを使ったrb-fseventでファイル監視が可能です。使い方は以下のように記述します。

INotify::Notifierのコンストラクタは以下のように定義されており、INotify::Native.inotify_initを呼び出します。

INotify::Notifier#watchはINotify::Watcherのインスタンスを生成します。

INotify::Watcherのコンストラクタ内では、Native.inotify_add_watchを呼び出して監視パスを追加し、自身をNotifierのwatchers変数に追加します。

INotify::Notifier#runは#processを呼び出し、#read_eventsで取得したイベントに対してコールバックを呼び出します。

#read_eventsは#readpartialを呼び出してデータを取得しEventの配列を返します。

#readpartialはイベントデータを取得しています。to_ioはNotifer.inotify_initで取得したファイルディスクリプタのIOオブジェクトです。IO#readpartialを呼び出すことでinotifyのイベントが来るまでブロックします。

Event#callback!は以下のような定義になっています。@watcher_idはinotify_add_watchで返された監視用のディスクリプタで、これをキーにNotifier#watchersからWatcherのインスタンスを取得し、Watcher#callback!を実行します。Watcher#callback!で実行される処理はNotifier#watchで指定したブロックになります。

Native.inotify_initやNative.inotify_add_watchはffiを使ってC関数を呼び出せるようにしています。

参考URL