Ruby - share logger instance among module/classes

后端 未结 9 1715
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-04 06:45

Working on a little Ruby script that goes out to the web and crawls various services. I\'ve got a module with several classes inside:

module Crawler
  class          


        
9条回答
  •  [愿得一人]
    2020-12-04 07:10

    As Zenagray points out, logging from class methods was left out of Jacob's answer. A small addition solves that:

    require 'logger'
    
    module Logging
      class << self
        def logger
          @logger ||= Logger.new($stdout)
        end
    
        def logger=(logger)
          @logger = logger
        end
      end
    
      # Addition
      def self.included(base)
        class << base
          def logger
            Logging.logger
          end
        end
      end
    
      def logger
        Logging.logger
      end
    end
    

    The intended use is via "include":

    class Dog
      include Logging
    
      def self.bark
        logger.debug "chirp"
        puts "#{logger.__id__}"
      end
    
      def bark
        logger.debug "grrr"
        puts "#{logger.__id__}"
      end
    end
    
    class Cat
      include Logging
    
      def self.bark
        logger.debug "chirp"
        puts "#{logger.__id__}"
      end
    
      def bark
        logger.debug "grrr"
        puts "#{logger.__id__}"
      end
    end
    
    Dog.new.bark
    Dog.bark
    Cat.new.bark
    Cat.bark
    

    Produces:

    D, [2014-05-06T22:27:33.991454 #2735] DEBUG -- : grrr
    70319381806200
    D, [2014-05-06T22:27:33.991531 #2735] DEBUG -- : chirp
    70319381806200
    D, [2014-05-06T22:27:33.991562 #2735] DEBUG -- : grrr
    70319381806200
    D, [2014-05-06T22:27:33.991588 #2735] DEBUG -- : chirp
    70319381806200
    

    Note the id of the logger is the same in all four cases. If you want a different instance for each class, then don't use Logging.logger, rather use self.class.logger:

    require 'logger'
    
    module Logging
      def self.included(base)
        class << base
          def logger
            @logger ||= Logger.new($stdout)
          end
    
          def logger=(logger)
            @logger = logger
          end
        end
      end
    
      def logger
        self.class.logger
      end
    end
    

    The same program now produces:

    D, [2014-05-06T22:36:07.709645 #2822] DEBUG -- : grrr
    70350390296120
    D, [2014-05-06T22:36:07.709723 #2822] DEBUG -- : chirp
    70350390296120
    D, [2014-05-06T22:36:07.709763 #2822] DEBUG -- : grrr
    70350390295100
    D, [2014-05-06T22:36:07.709791 #2822] DEBUG -- : chirp
    70350390295100
    

    Note that the first two id's are the same but are different from the 2nd two ids showing that we have two instances -- one for each class.

提交回复
热议问题