new_constants_in(*descs)
public
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.
Show source
def new_constants_in(*descs)
log_call(*descs)
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
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
aborting = false
ensure
new_constants = watch_frames.collect do |mod_name, prior_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
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
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