On Tue, Nov 06, 2012 at 01:36:53PM +0100, Xavier Noria wrote: > On Tue, Nov 6, 2012 at 12:37 PM, Aaron Patterson > <[email protected]> wrote: > > > Hi, > > > > I've changed `const_get` in Ruby 2.0. If it were implemented in 1.9, it > > would look roughly like this: > > > > def const_get name, inherited = true > > name.to_s.split('::').inject(self.class) do |klass, name| > > klass.const_get name, inherited > > end > > end > > > > I was hoping we could use this to replace the implementation of > > `constantize`, but it seems we have an inconsistency in the way that > > `constantize` works in regard to constant inheritance. > > > > I've written a test to demonstrate the problem: > > > > https://gist.github.com/4024158 > > > > For some reason `constantize` inherits constants, but not when the > > constant is defined on Object, where `const_get` in Ruby 2.0 will always > > honor the inheritance (even if the constant is defined at the top). > > > > Is there any chance we can change this? > > Yeah, at first sight they seem to be different in their intention. The > new const_get is implemented as a recursive const_get, whereas > constantize is closer to emulate the resolution algorithm for constant > paths. > > The subtle difference is in modules, as the test shows. > > As you know, X::String raises a NameError if X is a module, and > resolves with a warning if X is a class that inherits from Object, > because Object is among its ancestors but the access is considered > dubious anyway. That's what constantize kinda emulates. I believe > "constantize" also raises if X is a class, and always treats the first > constant in the path as if it had a leading double colon "::", that's > why I say "kinda". > > "Admin::UsersController".constantize fails if such controller does not > exist, regardless of the existence of an eventual top-level > UsersController, whereas if I understand it correctly > Object.const_get("Admin::UsersController", true) would resolve to such > top-level controller, because the original const_get name, inherit > does check Object by hand for modules, as the algorithm for relative > constant names does.
That is correct. This implementation const_get would find class. > Not sure about changing that behavior. Neither am I, that's why I emailed. ;-) It's a shame, I'm not actually sure what the new `const_get` buys us if we can't replace this method. :'( -- Aaron Patterson http://tenderlovemaking.com/ -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.
