Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
493 views
in Technique[技术] by (71.8m points)

rubygems - Load two Ruby Modules/Gems with the same name

I'm trying to use two Gems to access Amazon Web Services (AWS). One is the Amazon 'aws-sdk', the other is 'amazon-ec2'. I'm using the second as the aws-sdk does not cover the cloudwatch section of the amazon services.

The issue is that both load into the same namespace.

require 'aws-sdk'         # aws-sdk gem
require 'AWS'             # amazon-ec2 gem

config = {:access_key_id => 'abc', :secret_key => 'xyz'}

# start using the API with aws-sdk
ec2 = AWS::EC2.new(config)  

# start using the API for anazon-ec2
cw = AWS::Cloudwatch::Base.new(config) 

Now this understandably throws an error on the last line as the AWS module is pointing at the first required library, in this case aws-sdk.

NameError: uninitialized constant AWS::Cloudwatch

So, is it possible for me to load one of those into another namespace? Something like

require 'aws-sdk', 'AWS_SDK'
require 'AWS', 'AWS_EC2'

ec2 = AWS_SDK::EC2.new(config)  
cw = AWS_EC2::Cloudwatch::Base.new(config) 

Or is there another trick I could use here?

Thanks

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In Ruby, modules with the same name from different gems don't replace each other. If one gem implements

module AWS
  class Foo
  end
end

and another implements

module AWS
  class Bar
  end
end

and you require them both, you will end up with an AWS module that contains both a class Foo and a class Bar (unless the second does something really tricky like explicitly undefining anything already present in the module, before defining its own stuff, which is very unlikely). As long as the second gem doesn't redefine any methods in the first gem (or attempts to use a module as a class or vice versa), they should both work fine. I think you may be looking for the wrong solution.

Edit: And in fact, what happens for me (in an environment with only these gems present (aws-sdk 1.2.3 and amazon-ec2 0.9.17) and the exact code you listed above) is exactly that:

.rvm/gems/ree-1.8.7-2011.03@ec2/gems/amazon-ec2-0.9.17/lib/AWS/EC2.rb:2: EC2 is not a module (TypeError)

Could it be that an error gets swallowed somewhere and that the module AWS::Cloudwatch hasn't been defined, simply because the initialization of the gem goes awry?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...