Permalink
Browse files

Refactor ObjectSpace patch to DRY it up.

Also, Added unit tests for ObjectSpace patch.
And added some debugging statements using logger.devel
  • Loading branch information...
dcu committed Jul 4, 2012
1 parent 7db184a commit d9ab01665534a66b6f891a2efbc6b377c8134b76
@@ -60,7 +60,6 @@ def load_paths
#
def load!
return false if loaded?
puts "Started to load Padrino environment"
t = Time.now
@_called_from = first_caller
@@ -75,7 +74,7 @@ def load!
Padrino::Reloader.run!
Thread.current[:padrino_loaded] = true
puts "Loaded in #{Time.now - t}"
Padrino.logger.devel "Loaded Padrino in #{Time.now - t} seconds"
end
##
@@ -168,9 +167,11 @@ def require_dependencies(*paths)
Padrino::Reloader.safe_load(file, options.dup)
files.delete(file)
rescue LoadError => e
Padrino.logger.devel "Problem while loading #{file}: #{e.to_s}"
errors << e
failed << file
rescue NameError => e
Padrino.logger.devel "Problem while loading #{file}: #{e.to_s}"
errors << e
failed << file
rescue Exception => e
@@ -133,7 +133,7 @@ def safe_load(file, options={})
end
# Duplicate objects and loaded features before load file
ObjectSpace.snapshot
klasses = ObjectSpace.classes
files = Set.new($LOADED_FEATURES.dup)
# Now we can reload dependencies of our file
@@ -155,7 +155,7 @@ def safe_load(file, options={})
logger.error "Cannot require #{file} due to a syntax error: #{e.message}"
ensure
$-v = verbosity_was
new_constants = ObjectSpace.diff_classes
new_constants = ObjectSpace.new_classes(klasses)
if loaded
# Store the file details
LOADED_CLASSES[file] = new_constants
@@ -110,35 +110,50 @@ def classify
module ObjectSpace
class << self
##
# Returns all the classes in the object space.
# Optionally, a block can be passed, for example the following code
# would return the classes that start with the character "A":
#
# ObjectSpace.classes do |klass|
# if klass.to_s[0] == "A"
# klass
# end
# end
#
def classes(&block)
rs = Set.new
ObjectSpace.each_object(Class).each do |klass|
rs << if block
block.call(klass)
if block
if r = block.call(klass)
# add the returned value if the block returns something
rs << r
end
else
klass
rs << klass
end
end
rs
end
def snapshot
@snapshot = ObjectSpace.classes
end
def diff_classes
rs = Set.new
ObjectSpace.each_object(Class).each do |klass|
if !@snapshot.include?(klass)
rs << klass
##
# Returns a list of existing classes that are not included in "snapshot"
# This method is useful to get the list of new classes that were loaded
# after an event like requiring a file.
# Usage:
#
# snapshot = ObjectSpace.classes
# # require a file
# ObjectSpace.new_classes(snapshot)
#
def new_classes(snapshot)
self.classes do |klass|
if !snapshot.include?(klass)
klass
end
end
rs
end
end
end
@@ -0,0 +1,56 @@
require File.expand_path(File.dirname(__FILE__) + '/helper')
describe "ObjectSpace" do
def setup
end
def teardown
end
context "#classes" do
should "take an snapshot of the current loaded classes" do
snapshot = ObjectSpace.classes
assert_equal snapshot.include?(Padrino::Logger), true
end
should "return a Set object" do
snapshot = ObjectSpace.classes
assert_equal snapshot.kind_of?(Set), true
end
should "be able to process a the class name given a block" do
klasses = ObjectSpace.classes do |klass|
if klass.to_s =~ /^Padrino::/
klass
end
end
assert_equal (klasses.size > 1), true
klasses.each do |klass|
assert_match /^Padrino::/, klass.to_s
end
end
end
context "#new_classes" do
setup do
@snapshot = ObjectSpace.classes
end
should "return list of new classes" do
class OSTest; end
module OSTestModule; class B; end; end
new_classes = ObjectSpace.new_classes(@snapshot)
assert_equal new_classes.size, 2
assert_equal new_classes.include?(OSTest), true
assert_equal new_classes.include?(OSTestModule::B), true
end
should "return a Set object" do
new_classes = ObjectSpace.new_classes(@snapshot)
assert_equal new_classes.kind_of?(Set), true
end
end
end

0 comments on commit d9ab016

Please sign in to comment.