ファイルの監視3
http://d.hatena.ne.jp/walf443/20070302/1172849934
の続き
分かった。Pathnameを使えばもっと幅の広い監視ができそう。おまけに名前も困らない。(とおもったら一文字足りない。pathname-observer) Pathname#entriesを使って新しいファイルが追加されたらとかもできると思う。*1
==> lib/pathname/observer.rb <== require 'pathname' require 'observer' $LOAD_PATH.unshift(File.expand_path(File.join(File.dirname(__FILE__), '../'))) require 'pathname/observe_manager' class Pathname class Observer def initialize(path, &block) @path = Pathname.new(path) unless @path.exist? raise ArgumentError end @proc = block end def path @path end def update path, result if @path.to_s == path.to_s @proc.call(@path.to_s, result) end end end end ==> lib/pathname/observe_manager.rb <== require File.join(File.dirname(__FILE__), '../', 'pathname/observer') class Pathname class ObserveManager include Observable def initialize glob_expr=nil, interval=1, &block @interval = interval if glob_expr add_paths glob_expr, &block end end attr_accessor :interval def add_paths glob_expr, &block Pathname.glob(glob_expr).each do |pathname| add_observer(Pathname::Observer.new(pathname, &block)) end end def observe method last_result_of = {} @observer_peers.each do |observer| last_result_of[observer.path.to_s] = observer.path.__send__(method) end loop do begin sleep @interval current_result_of = {} @observer_peers.each do |observer| current_result_of[observer.path.to_s] = observer.path.__send__(method) end if (temp_touple = current_result_of.select {|key,val| val != last_result_of[key]}).size > 0 temp_touple.each do |hash| changed notify_observers(hash.first, hash.last) end last_result_of = current_result_of end rescue Interrupt return rescue Exception next end end end end end if $PROGRAM_NAME == __FILE__ observe_manager = Pathname::ObserveManager.new('*.txt') {|path, result| puts "#{path} updated on #{result}" } observe_manager.observe(:mtime) end
*1:追記: pathobserverで登録してみた