-
Notifications
You must be signed in to change notification settings - Fork 21.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve ActiveSupport::Dependencies code understanding #24205
Improve ActiveSupport::Dependencies code understanding #24205
Conversation
Thanks for the pull request, and welcome! The Rails team is excited to review your changes, and you should hear from @pixeltrix (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
3550ea9
to
dd57e47
Compare
r? @fxn |
@@ -665,7 +665,7 @@ def new_constants_in(*descs) | |||
new_constants = constant_watch_stack.new_constants | |||
|
|||
return new_constants unless aborting | |||
|
|||
# Removing partially loaded constants when error occurred during loading. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's something strange here, already present before we removed the traces: the comment says an error condition is going on if you reached this point. This should be obvious from reading the source.
I think this could be rewritten to be more clear. Instead of aborting
let's use a flag with the opposite meaning like success
. Then we can just say:
if success
new_constants
else
# Remove partially loaded constants.
new_constants.each { |c| remove_constant(c) }.clear
end
The intention to reverse the flag is to have the optimistic path first in the if/else.
@fxn Thank you for your elaborate review, really appreciated! Just pushed a commit that incorporates your feedback 😬 |
Could still be simpler (just iterating over this already existing piece of code since we are on it, also with an intention to go through a little refactor since you are students and it may be interesting to see these kind of arguments). Why does it need a What about (written right here): def new_constants_in(*descs)
constant_watch_stack.watch_namespaces(descs)
success = false
begin
yield # Now yield to the code that is to define new constants.
success = true
ensure
new_constants = constant_watch_stack.new_constants
if success
new_constants
else
# Remove partially loaded constants.
new_constants.each { |c| remove_constant(c) }
[]
end
end
end Note the Also removed the |
@fxn Thanks again for your in-depth explanation. I agree with you on removing the I am in no way an experienced Ruby user. However, if I understand correctly |
Aahhh, you're totally right! Was typing off the top of my head and mislead by the final array. Let me come back with a different refactor. |
Here's another rewrite: def new_constants_in(*descs)
constant_watch_stack.watch_namespaces(descs)
begin
yield # Now yield to the code that is to define new constants.
rescue Exception
# Remove partially loaded constants.
constant_watch_stack.new_constants.each do |new_constant|
remove_constant(new_constant)
end
raise
else
constant_watch_stack.new_constants
end
end I think it more straightforward than the current def new_constants_in(*descs)
constant_watch_stack.watch_namespaces(descs)
aborting = true
begin
yield # Now yield to the code that is to define new constants.
aborting = false
ensure
new_constants = constant_watch_stack.new_constants
return new_constants unless aborting
new_constants.each { |c| remove_constant(c) }.clear
end
[]
end I bet the intention of the original |
I think we need the ensure; it's the only block that will be run for some forms of stack unwind. |
@matthewd which workflow would work on the current code and not the refactored one? |
Non-exception stack unwinds: throws and non-local returns are the ones that come to mind. |
@matthewd but are you talking about the above implementation, or thinking about an eventual refactor in which a |
We don't control the contents of the block we're yielding to. Okay, a non-local return would be tricky to achieve in a top-level file context, but a throw is perfectly possible. |
I was not aware that Can't see it in Flanagan's or Ruby docs, I find it a bit surprising Both implementations are not equivalent then. |
Added coverage for that situation, the test in 52ce6ec passes with the current implementation and fails with the alternative above. |
I have worked a little bit more on this method. There is now test coverage for both raising and throwing, and includes checking for autoloading recursion. Then I did some project archeology and saw the origin or the unreachable line with the array literal, see the commit message of 4b80395. Then removed the @aaronang needs a rebase then. After all this thinking about this method I believe we would only reverse the flag. I prefer to read the positive/optimistic return new_constants if success than return new_constants unless aborting In this case I also prefer the |
In a previous patch, all log-related stuff was removed. However, some logs are still useful to understand the code. Therefore, in this patch, I put those log messages back as comments. [ci skip]
882abcf
to
901a407
Compare
@fxn Incorporated your feedback 😉 It's cool to see how you discuss things so elaborate. Unfortunately, Travis CI failed in the Action Cable module. Is there anything I can do about this? |
@aaronang don't worry, the patch seems correct, passed locally right? |
@aaronang just in case I mean the AS suite, no need to run Action Cable's. |
@fxn The Active Support test suite passes locally 😉 |
Awesome, in then, thanks a lot! ❤️ |
…endencies Improve ActiveSupport::Dependencies code understanding
❤️ 💎 |
@fxn Feel free to approach us again with other tasks 😬 |
Summary
In pull request #24198, I removed all log-related stuff in
ActiveSupport::Dependencies
as this was no longer useful. However, some of the log messages were still useful to understand the code. Therefore, in this patch, those messages are put back as comments.Other Information
Please have a look at pull request #24198 as reference.
Looking forward to hearing from you 😄