バリケンのRuby日記 RSSフィード

2006-06-15

[] QuickMLソースコードを読む(8) /usr/lib/ruby/1.8/quickml/logger.rb  QuickMLのソースコードを読む(8) /usr/lib/ruby/1.8/quickml/logger.rb - バリケンのRuby日記 を含むブックマーク はてなブックマーク -  QuickMLのソースコードを読む(8) /usr/lib/ruby/1.8/quickml/logger.rb - バリケンのRuby日記  QuickMLのソースコードを読む(8) /usr/lib/ruby/1.8/quickml/logger.rb - バリケンのRuby日記 のブックマークコメント

おとといの日記で、QuickML::Configクラスの定義ではQuickML::LoggerクラスインスタンスQuickML::GetText::Catalogクラスインスタンスを生成しているのがわかったね。

じゃあ、今日からは「QuickML::Loggerクラス」の定義が書かれている「/usr/lib/ruby/1.8/quickml/logger.rb」のコードを読んでいくよ。

#
# quickml/logger - a part of quickml server
#
# Copyright (C) 2002-2004 Satoru Takabayashi <satoru@namazu.org>
#     All rights reserved.
#     This is free software with ABSOLUTELY NO WARRANTY.
#
# You can redistribute it and/or modify it under the terms of
# the GNU General Public License version 2.
#
require 'quickml/utils'
require 'thread'

module QuickML
  class Logger
    def initialize (log_filename, verbose_mode = nil)
      @mutex = Mutex.new
      @log_file = File.safe_open(log_filename, "a")
      @log_file.sync = true
      @verbose_mode = verbose_mode
    end

    private
    def puts_log (msg)
      @mutex.synchronize {
        time = Time.now.strftime("%Y-%m-%dT%H:%M:%S")
        @log_file.puts "#{time}: #{msg}"
      }
    end

    public
    def log (msg)
      puts_log(msg)
    end

    def vlog (msg)
      puts_log(msg) if @verbose_mode
    end

    def reopen
      @mutex.synchronize {
        log_filename = @log_file.path
        @log_file.close
        @log_file = File.safe_open(log_filename, "a")
      }
    end
  end
end

じゃあ、順に読んでいこうか。

require

require 'quickml/utils'
require 'thread'

これは、Kernel#requireメソッドで「/usr/lib/ruby/1.8/quickml/utils.rb」「/usr/lib/ruby/1.8/thread.rb」をrubyスクリプトとして読んでいるよ。

QuickML::Loggerクラスのinitialize

module QuickML
  class Logger
    def initialize (log_filename, verbose_mode = nil)
      @mutex = Mutex.new
      @log_file = File.safe_open(log_filename, "a")
      @log_file.sync = true
      @verbose_mode = verbose_mode
    end

とくに説明は不要かな?Mutexスレッドロックを制御するオブジェクトだったよね。また、File::safe_openメソッドは/usr/lib/ruby/1.8/quickml/utils.rbで定義されているんだよね。あとIO#sync=メソッドは、trueにするとsyncモード(同期モードバッファリングせずにすぐに書き込むモード)になるよ。

QuickML::Logger#puts_logメソッド

    private
    def puts_log (msg)
      @mutex.synchronize {
        time = Time.now.strftime("%Y-%m-%dT%H:%M:%S")
        @log_file.puts "#{time}: #{msg}"
      }
    end

このメソッドはprivateだから、インスタンスメソッドとしては使えないよ。

Mutex#synchronizeメソッドは、与えられたブロックを実行中にスレッドロックするメソッドだね。

ブロックの中身は、現在時刻と引数で与えられたmsgを@log.fileに対してIO#putsメソッドで出力しているよ。

QuickML::Logger#logメソッド

    public
    def log (msg)
      puts_log(msg)
    end

ここからはpublicなメソッドになるから、インスタンスメソッドとして使うことが出来るよ。

QuickML::Logger#logメソッドは、さっきのprivateなQuickML::Logger#puts_logメソッドを呼び出しているよ。

QuickML::Logger#vlogメソッド

    def vlog (msg)
      puts_log(msg) if @verbose_mode
    end

QuickML::Logger#vlogメソッドは、@verbose_modeがtrueなら、privateなQuickML::Logger#puts_logメソッドを呼び出す、というものだよ。

QuickML::Logger#reopenメソッド

    def reopen
      @mutex.synchronize {
        log_filename = @log_file.path
        @log_file.close
        @log_file = File.safe_open(log_filename, "a")
      }
    end
  end
end

QuickML::Logger#reopenメソッドは、スレッドロックしてファイルを開きなおしているよ。ちなみにFile#pathファイルオープンしたときのパス指定文字列、IO#closeファイルクローズだよ。

今日はここまで。/usr/lib/ruby/1.8/quickml/logger.rbファイルは小さかったね。

トラックバック - http://rubyist.g.hatena.ne.jp/muscovyduck/20060615