def new_constants_in(*descs)
      log_call(*descs)

      # Build the watch frames. Each frame is a tuple of
      #   [module_name_as_string, constants_defined_elsewhere]
      watch_frames = descs.collect do |desc|
        if desc.is_a? Module
          mod_name = desc.name
          initial_constants = desc.local_constant_names
        elsif desc.is_a?(String) || desc.is_a?(Symbol)
          mod_name = desc.to_s

          # Handle the case where the module has yet to be defined.
          initial_constants = if qualified_const_defined?(mod_name)
            mod_name.constantize.local_constant_names
          else
            []
          end
        else
          raise Argument, "#{desc.inspect} does not describe a module!"
        end

        [mod_name, initial_constants]
      end

      constant_watch_stack_mutex.synchronize do
        constant_watch_stack.concat watch_frames
      end

      aborting = true
      begin
        yield # Now yield to the code that is to define new constants.
        aborting = false
      ensure
        # Find the new constants.
        new_constants = watch_frames.collect do |mod_name, prior_constants|
          # Module still doesn't exist? Treat it as if it has no constants.
          next [] unless qualified_const_defined?(mod_name)

          mod = mod_name.constantize
          next [] unless mod.is_a? Module
          new_constants = mod.local_constant_names - prior_constants

          # Make sure no other frames takes credit for these constants.
          constant_watch_stack_mutex.synchronize do
            constant_watch_stack.each do |frame_name, constants|
              constants.concat new_constants if frame_name == mod_name
            end
          end

          new_constants.collect do |suffix|
            mod_name == "Object" ? suffix : "#{mod_name}::#{suffix}"
          end
        end.flatten

        log "New constants: #{new_constants * ', '}"

        if aborting
          log "Error during loading, removing partially loaded constants "
          new_constants.each { |name| remove_constant name }
          new_constants.clear
        end
      end

      return new_constants
    ensure
      # Remove the stack frames that we added.
      if defined?(watch_frames) && ! watch_frames.blank?
        frame_ids = watch_frames.collect { |frame| frame.object_id }
        constant_watch_stack_mutex.synchronize do
          constant_watch_stack.delete_if do |watch_frame|
            frame_ids.include? watch_frame.object_id
          end
        end
      end
    end
def new_constants_in(*descs)
      log_call(*descs)

      # Build the watch frames. Each frame is a tuple of
      #   [module_name_as_string, constants_defined_elsewhere]
      watch_frames = descs.collect do |desc|
        if desc.is_a? Module
          mod_name = desc.name
          initial_constants = desc.local_constant_names
        elsif desc.is_a?(String) || desc.is_a?(Symbol)
          mod_name = desc.to_s

          # Handle the case where the module has yet to be defined.
          initial_constants = if qualified_const_defined?(mod_name)
            mod_name.constantize.local_constant_names
          else
            []
          end
        else
          raise Argument, "#{desc.inspect} does not describe a module!"
        end

        [mod_name, initial_constants]
      end

      constant_watch_stack_mutex.synchronize do
        constant_watch_stack.concat watch_frames
      end

      aborting = true
      begin
        yield # Now yield to the code that is to define new constants.
        aborting = false
      ensure
        # Find the new constants.
        new_constants = watch_frames.collect do |mod_name, prior_constants|
          # Module still doesn't exist? Treat it as if it has no constants.
          next [] unless qualified_const_defined?(mod_name)

          mod = mod_name.constantize
          next [] unless mod.is_a? Module
          new_constants = mod.local_constant_names - prior_constants

          # Make sure no other frames takes credit for these constants.
          constant_watch_stack_mutex.synchronize do
            constant_watch_stack.each do |frame_name, constants|
              constants.concat new_constants if frame_name == mod_name
            end
          end

          new_constants.collect do |suffix|
            mod_name == "Object" ? suffix : "#{mod_name}::#{suffix}"
          end
        end.flatten

        log "New constants: #{new_constants * ', '}"

        if aborting
          log "Error during loading, removing partially loaded constants "
          new_constants.each { |name| remove_constant name }
          new_constants.clear
        end
      end

      return new_constants
    ensure
      # Remove the stack frames that we added.
      if defined?(watch_frames) && ! watch_frames.blank?
        frame_ids = watch_frames.collect { |frame| frame.object_id }
        constant_watch_stack_mutex.synchronize do
          constant_watch_stack.delete_if do |watch_frame|
            frame_ids.include? watch_frame.object_id
          end
        end
      end
    end
Run the provided block and detect the new constants that were loaded during
 its execution. Constants may only be regarded as 'new' once -- so if the
 block calls +new_constants_in+ again, then the constants defined within the
 inner call will not be reported in this one.

 If the provided block does not run to completion, and instead raises an
 exception, any new constants are regarded as being only partially defined
 and will be removed immediately.