lib/configurability.rb in configurability-1.0.2 vs lib/configurability.rb in configurability-1.0.3

- old
+ new

@@ -7,21 +7,25 @@ # @author Michael Granger <ged@FaerieMUD.org> # module Configurability # Library version constant - VERSION = '1.0.2' + VERSION = '1.0.3' # Version-control revision constant - REVISION = %q$Revision: 17a6999c08b9 $ + REVISION = %q$Revision: ec3f030074dc $ - require 'configurability/logformatter.rb' + require 'configurability/logformatter' + require 'configurability/deferredconfig' ### The objects that have had Configurability added to them @configurable_objects = [] + ### The loaded config (if there is one) + @loaded_config = nil + ### Logging @default_logger = Logger.new( $stderr ) @default_logger.level = $DEBUG ? Logger::DEBUG : Logger::WARN @default_log_formatter = Configurability::LogFormatter.new( @default_logger ) @@ -34,10 +38,14 @@ # @return [Array] the Array of objects that have had Configurability # added to them attr_accessor :configurable_objects + # @return [Object] the loaded configuration (after ::configure_objects + # has been called at least once) + attr_accessor :loaded_config + # @return [Logger::Formatter] the log formatter that will be used when the logging # subsystem is reset attr_accessor :default_log_formatter # @return [Logger] the logger that will be used when the logging subsystem is reset @@ -53,10 +61,17 @@ ### Add configurability to the given +object+. def self::extend_object( object ) self.log.debug "Adding Configurability to %p" % [ object ] super self.configurable_objects << object + + # If the config has already been propagated, add deferred configuration to the extending + # object in case it overrides #configure later. + if (( config = self.loaded_config )) + self.install_config( config, object ) + object.extend( Configurability::DeferredConfig ) + end end ### Mixin hook: extend including classes instead def self::included( mod ) @@ -67,11 +82,13 @@ ### Try to generate a config key from the given object. If it responds_to #name, ### the result will be stringified and stripped of non-word characters. If the ### object itself doesn't have a name, the name of its class will be used instead. def self::make_key_from_object( object ) if object.respond_to?( :name ) - return object.name.sub( /.*::/, '' ).gsub( /\W+/, '_' ).downcase.to_sym + name = object.name + name = 'anonymous' if name.nil? || name.empty? + return name.sub( /.*::/, '' ).gsub( /\W+/, '_' ).downcase.to_sym elsif object.class.name && !object.class.name.empty? return object.class.name.sub( /.*::/, '' ).gsub( /\W+/, '_' ).downcase.to_sym else return :anonymous end @@ -85,37 +102,50 @@ ### instead. def self::configure_objects( config ) self.log.debug "Splitting up config %p between %d objects with configurability." % [ config, self.configurable_objects.length ] - self.configurable_objects.each do |obj| - section = obj.config_key.to_sym - self.log.debug "Configuring %p with the %p section of the config." % - [ obj, section ] + self.loaded_config = config - if config.respond_to?( section ) - self.log.debug " config has a %p method; using that" % [ section ] - obj.configure( config.send(section) ) - elsif config.respond_to?( :[] ) - self.log.debug " config has a an index operator method; using that" - obj.configure( config[section] || config[section.to_s] ) - else - self.log.warn " don't know how to get the %p section of the config from %p" % - [ section, config ] - obj.configure( nil ) - end + self.configurable_objects.each do |obj| + self.install_config( config, obj ) end end + ### If a configuration has been loaded (via {#configure_objects}), clear it. + def self::reset + self.loaded_config = nil + end + + ### Reset the global logger object to the default ### @return [void] def self::reset_logger self.logger = self.default_logger self.logger.level = Logger::WARN self.logger.formatter = self.default_log_formatter end + + ### Install the appropriate section of the +config+ into the given +object+. + def self::install_config( config, object ) + section = object.config_key.to_sym + self.log.debug "Configuring %p with the %p section of the config." % + [ object, section ] + + if config.respond_to?( section ) + self.log.debug " config has a %p method; using that" % [ section ] + object.configure( config.send(section) ) + elsif config.respond_to?( :[] ) + self.log.debug " config has a an index operator method; using that" + object.configure( config[section] || config[section.to_s] ) + else + self.log.warn " don't know how to get the %p section of the config from %p" % + [ section, config ] + object.configure( nil ) + end + end ############################################################# ### A P P E N D E D M E T H O D S #############################################################