Fixes capture method issues when ActiveSupport Kernel extensions are loaded after a namespace is defined (code added before fixes when AS is loaded before the namespace is defined). Given the new use of capture in the deploy:clean task, AS would have to be loaded before the deploy recipe to work with the existing code.
It's ugly but it seems to work to fix capture even if loaded after a namespace is defined. It's based on similar strategies for recreating BasicObject in Ruby 1.8.
Fixes #175 #168 #170 #239 #169
Listen for method definition on Kernel and undefine on Namespace
Fixes capture method issues when ActiveSupport Kernel extensions are
loaded after a namespace is defined.
What does the snippet return result if self != Kernel do?
return result if self != Kernel
It skips the rest of the callback if the method was added to a class other than Kernel since nearly all classes won't have the callback defined.
Hi, I have a few more niggling questions.
Ok, that makes sense. I am aware of the method_missing lookup functionality of Namespace, and now I'm convinced that it is the only affected component. As for the unit tests, what do you mean by "original commit"? I see two unit test lines removed.
@cgriego From what I can see, removing those two lines of unit test code just masks other problems. The unit test should pass with them in place. That said, I tried removing the explicitly_define_clashing_kernel_methods method and everything passed. Actually, I have no clue what that particular method does and how it can be correct. Do you see any reason to justify its existence, in light of your current fix?
This is the process I went through.
<"config"> expected but was
Removing the two lines from the existing test exposed the issue. It didn't mask other problem that I can see.
The explicitly_define_clashing_kernel_methods method is still needed in the case where conflicting methods are added to Kernel before the namespace file is required, which is a case that is very difficult to unit test.
@cgriego I think some topics are being conflated here. Removing those two lines changed the meaning of the unit test, and indeed your code fixed it and a lot more, being general purpose. It does not, however, address the original meaning of the unit test, which seems to fail with your code as an addition. Put those two removed lines back in, you will get the following.
NameError: undefined method `some_weird_method' for class `Capistrano::Configuration::Namespaces::Namespace'
/Users/royliu/Desktop/work/capistrano/lib/capistrano/configuration/namespaces.rb:206:in `block in explicitly_define_clashing_kernel_methods'
Unless I am mistaken and the original unit test no longer makes sense in light of the pull request changes, I think there's a bad interaction with the explicitly_define_clashing_kernel_methods method.
So there you have it, a reasonable unit test that fails unexpectedly: Even if the explicitly_define_clashing_kernel_methods method serves a purpose, I still don't think it's correct.
Merge pull request #242 from cgriego/capture
Fix capture by listening for method definition on Kernel and undefine on Namespace
Reconcile changes from pull request #242
@cgriego How does 8b3a188 look? Is it a reasonable replacement for the code I removed?