Issue with autoloading when there is a space in the constant string
ashiqueps opened this issue · comments
Problem
Unable to require fog/rackspace which was working fine in the previous versions and got busted in v2.3.0.
In #269, the author introduced the const_defined?
method to check whether the classes are already defined or not and avoid unnecessary loading. The problem with that is, the services are being called with a space in their constant_string, which results in raising the below exception when there is a space in the constant.
Example: https://github.com/fog/fog-rackspace/blob/master/lib/fog/rackspace.rb#L53
autoload :NetworkingV2, File.expand_path('../rackspace/networking_v2', __FILE__)
service(:cdn, 'CDN')
service(:cdn_v2, 'CDN v2')
In the previous versions, there was a rescue block to catch this error and prints a deprecation warning as below, but in fact, the functionality was working fine.
[fog][DEPRECATION] Unable to load Fog::Rackspace::CDN v2 [fog][DEPRECATION] Falling back to deprecated constant Fog::CDN v2::Rackspace. The preferred format of service provider constants has changed from service::provider to provider::service. Please update this service provider to use the preferred format.
Version
fog-core v2.3.0
Steps to reproduce
- Install the gem fog-rackspace, which by default installs the latest version of fog-core
- In the irb, run
require "fog/rackspace"
Stacktrace
3.1.0 :001 > require 'fog/rackspace'
/Users/user/.rvm/gems/ruby-3.1.0/gems/fog-core-2.3.0/lib/fog/core/provider.rb:50:in `const_defined?': wrong constant name CDN v2 (NameError)
if const_defined?([to_s, constant_string].join("::"))
^^^^^^^^^^^^^^
from /Users/user/.rvm/gems/ruby-3.1.0/gems/fog-core-2.3.0/lib/fog/core/provider.rb:50:in `service_klass'
from /Users/user/.rvm/gems/ruby-3.1.0/gems/fog-core-2.3.0/lib/fog/core/provider.rb:37:in `service'
from /Users/user/.rvm/gems/ruby-3.1.0/gems/fog-rackspace-0.1.6/lib/fog/rackspace.rb:54:in `<module:Rackspace>'
from /Users/user/.rvm/gems/ruby-3.1.0/gems/fog-rackspace-0.1.6/lib/fog/rackspace.rb:28:in `<module:Fog>'
from /Users/user/.rvm/gems/ruby-3.1.0/gems/fog-rackspace-0.1.6/lib/fog/rackspace.rb:10:in `<top (required)>'
from <internal:/Users/user/.rvm/rubies/ruby-3.1.0/lib/ruby/3.1.0/rubygems/core_ext/kernel_require.rb>:160:in `require'
from <internal:/Users/user/.rvm/rubies/ruby-3.1.0/lib/ruby/3.1.0/rubygems/core_ext/kernel_require.rb>:160:in `rescue in require'
from <internal:/Users/user/.rvm/rubies/ruby-3.1.0/lib/ruby/3.1.0/rubygems/core_ext/kernel_require.rb>:149:in `require'
from (irb):1:in `<main>'
from /Users/user/.rvm/rubies/ruby-3.1.0/lib/ruby/gems/3.1.0/gems/irb-1.4.1/exe/irb:11:in `<top (required)>'
from /Users/user/.rvm/rubies/ruby-3.1.0/bin/irb:25:in `load'
from /Users/user/.rvm/rubies/ruby-3.1.0/bin/irb:25:in `<main>'
<internal:/Users/user/.rvm/rubies/ruby-3.1.0/lib/ruby/3.1.0/rubygems/core_ext/kernel_require.rb>:85:in `require': cannot load such file -- fog/rackspace (LoadError)
from <internal:/Users/user/.rvm/rubies/ruby-3.1.0/lib/ruby/3.1.0/rubygems/core_ext/kernel_require.rb>:85:in `require'
from (irb):1:in `<main>'
from /Users/user/.rvm/rubies/ruby-3.1.0/lib/ruby/gems/3.1.0/gems/irb-1.4.1/exe/irb:11:in `<top (required)>'
from /Users/user/.rvm/rubies/ruby-3.1.0/bin/irb:25:in `load'
from /Users/user/.rvm/rubies/ruby-3.1.0/bin/irb:25:in `<main>'
3.1.0 :002 >
Possible Solution
Before calling the const_defined? method, replace the spaces with :: operator so that it will be a valid constant name to search in the module.
@ashiqueps - Thanks for the detailed report. I guess we must have overlooked the case where there were whitespaces when we were working on this. Rather than changing fog-core stuff, could we remove the spaces in Rackspace? I see, for instance, that networking v2 doesn't use a whitespace, though CDN and compute do. That might be a safer change since it doesn't impact other fog stuff. Otherwise, I'm open to discussing a more general fix if we need to go that route.