Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitc03bba4

Browse files
committed
trace autoloads, and document hints for troubleshooting
Closes#32885.
1 parentc3e5695 commitc03bba4

File tree

3 files changed

+101
-4
lines changed

3 files changed

+101
-4
lines changed

‎activesupport/lib/active_support/dependencies.rb‎

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,12 @@ def self.unload_interlock
7979
# to allow arbitrary constants to be marked for unloading.
8080
mattr_accessor:explicitly_unloadable_constants,default:[]
8181

82+
# The logger used when tracing autoloads.
83+
mattr_accessor:logger
84+
85+
# If true, trace autoloads with +logger.debug+.
86+
mattr_accessor:verbose,default:false
87+
8288
# The WatchStack keeps a stack of the modules being watched as files are
8389
# loaded. If a file in the process of being loaded (parent.rb) triggers the
8490
# load of another file (child.rb) the stack will ensure that child.rb
@@ -416,7 +422,7 @@ def loadable_constants_for_path(path, bases = autoload_paths)
416422

417423
# Search for a file in autoload_paths matching the provided suffix.
418424
defsearch_for_file(path_suffix)
419-
path_suffix=path_suffix.sub(/(\.rb)?$/,".rb".freeze)
425+
path_suffix+=".rb"unlesspath_suffix.ends_with?(".rb")
420426

421427
autoload_paths.eachdo |root|
422428
path=File.join(root,path_suffix)
@@ -450,6 +456,7 @@ def autoload_module!(into, const_name, qualified_name, path_suffix)
450456
returnnilunlessbase_path=autoloadable_module?(path_suffix)
451457
mod=Module.new
452458
into.const_setconst_name,mod
459+
log("constant#{qualified_name} autoloaded (module autovivified from#{File.join(base_path,path_suffix)})")
453460
autoloaded_constants <<qualified_nameunlessautoload_once_paths.include?(base_path)
454461
autoloaded_constants.uniq!
455462
mod
@@ -491,7 +498,7 @@ def load_missing_constant(from_mod, const_name)
491498
raiseArgumentError,"A copy of#{from_mod} has been removed from the module tree but is still active!"
492499
end
493500

494-
qualified_name=qualified_name_forfrom_mod,const_name
501+
qualified_name=qualified_name_for(from_mod,const_name)
495502
path_suffix=qualified_name.underscore
496503

497504
file_path=search_for_file(path_suffix)
@@ -504,8 +511,13 @@ def load_missing_constant(from_mod, const_name)
504511
raise"Circular dependency detected while autoloading constant#{qualified_name}"
505512
else
506513
require_or_load(expanded,qualified_name)
507-
raiseLoadError,"Unable to autoload constant#{qualified_name}, expected#{file_path} to define it"unlessfrom_mod.const_defined?(const_name,false)
508-
returnfrom_mod.const_get(const_name)
514+
515+
iffrom_mod.const_defined?(const_name,false)
516+
log("constant#{qualified_name} autoloaded from#{expanded}.rb")
517+
returnfrom_mod.const_get(const_name)
518+
else
519+
raiseLoadError,"Unable to autoload constant#{qualified_name}, expected#{file_path} to define it"
520+
end
509521
end
510522
elsifmod=autoload_module!(from_mod,const_name,qualified_name,path_suffix)
511523
returnmod
@@ -554,6 +566,7 @@ def load_missing_constant(from_mod, const_name)
554566
# as the environment will be in an inconsistent state, e.g. other constants
555567
# may have already been unloaded and not accessible.
556568
defremove_unloadable_constants!
569+
log("removing unloadable constants")
557570
autoloaded_constants.each{ |const|remove_constantconst}
558571
autoloaded_constants.clear
559572
Reference.clear!
@@ -743,6 +756,10 @@ def remove_constant(const) #:nodoc:
743756
# The constant is no longer reachable, just skip it.
744757
end
745758
end
759+
760+
deflog(message)
761+
logger.debug("autoloading:#{message}")iflogger &&verbose
762+
end
746763
end
747764
end
748765

‎activesupport/test/dependencies_test.rb‎

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1130,3 +1130,52 @@ def test_load_and_require_stay_private
11301130
ActiveSupport::Dependencies.hook!
11311131
end
11321132
end
1133+
1134+
classDependenciesLogging <ActiveSupport::TestCase
1135+
MESSAGE="message"
1136+
1137+
defwith_settings(logger,verbose)
1138+
original_logger=ActiveSupport::Dependencies.logger
1139+
original_verbose=ActiveSupport::Dependencies.verbose
1140+
1141+
ActiveSupport::Dependencies.logger=logger
1142+
ActiveSupport::Dependencies.verbose=verbose
1143+
1144+
yield
1145+
ensure
1146+
ActiveSupport::Dependencies.logger=original_logger
1147+
ActiveSupport::Dependencies.verbose=original_verbose
1148+
end
1149+
1150+
deffake_logger
1151+
Class.newdo
1152+
defself.debug(message)
1153+
message
1154+
end
1155+
end
1156+
end
1157+
1158+
test"does not log if the logger is nil and verbose is false"do
1159+
with_settings(nil,false)do
1160+
assert_nilActiveSupport::Dependencies.log(MESSAGE)
1161+
end
1162+
end
1163+
1164+
test"does not log if the logger is nil and verbose is true"do
1165+
with_settings(nil,true)do
1166+
assert_nilActiveSupport::Dependencies.log(MESSAGE)
1167+
end
1168+
end
1169+
1170+
test"does not log if the logger is set and verbose is false"do
1171+
with_settings(fake_logger,false)do
1172+
assert_nilActiveSupport::Dependencies.log(MESSAGE)
1173+
end
1174+
end
1175+
1176+
test"logs if the logger is set and verbose is true"do
1177+
with_settings(fake_logger,true)do
1178+
assert_equal"autoloading:#{MESSAGE}",ActiveSupport::Dependencies.log(MESSAGE)
1179+
end
1180+
end
1181+
end

‎guides/source/autoloading_and_reloading_constants.md‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1350,3 +1350,34 @@ With the [Spring](https://github.com/rails/spring) pre-loader (included with new
13501350

13511351
Occasionally you may need to explicitly eager_load by using `Rails
13521352
.application.eager_load!` in the setup of your tests -- this might occur if your[tests involve multithreading](https://stackoverflow.com/questions/25796409/in-rails-how-can-i-eager-load-all-code-before-a-specific-rspec-test).
1353+
1354+
##Troubleshooting
1355+
1356+
###Tracing Autoloads
1357+
1358+
Active Support is able to report constants as they are autoloaded. To enable these traces in a Rails application, put the following two lines in some initializer:
1359+
1360+
```ruby
1361+
ActiveSupport::Dependencies.logger=Rails.logger
1362+
ActiveSupport::Dependencies.verbose=true
1363+
```
1364+
1365+
###Where is a Given Autoload Triggered?
1366+
1367+
If constant`Foo` is being autoloaded, and you'd like to know where is that autoload coming from, just throw
1368+
1369+
```ruby
1370+
putscaller
1371+
```
1372+
1373+
at the top of`foo.rb` and inspect the printed stack trace.
1374+
1375+
###Which Constants Have Been Autoloaded?
1376+
1377+
At any given time,
1378+
1379+
```ruby
1380+
ActiveSupport::Dependencies.autoloaded_constants
1381+
```
1382+
1383+
has the collection of constants that have been autoloaded so far.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp