use*_*029 9 ruby gem namespaces
给定一个定义顶级类的gem,它与我编写的一些代码冲突,是否可以以这样的方式要求gem,使其所有类都分组在我可以定义的模块中?例如,如果unsafe_gem定义了一个类:
class Word
# ... some code
end
Run Code Online (Sandbox Code Playgroud)
我需要这样的东西:
class Word
# My word class.
end
module SafeContainer
# This obviously doesn't work
# (i.e. the gem still defines ::Word).
require 'unsafe_gem'
end
Run Code Online (Sandbox Code Playgroud)
这样我就可以区分:
Word.new # => The class I defined.
SafeContainer::Word.new # => The class defined by the gem.
Run Code Online (Sandbox Code Playgroud)
一些进一步的细节:我的代码(例如'Word'类)已经包装在它自己的命名空间中.但是,我希望能够为用户提供启用"语法糖"形式的选项,这使得某些类可以在顶级命名空间下直接访问.但是,这会与我正在使用的一个宝石创建一个名称冲突,它定义了一个顶级类.目前提出的解决方案都不起作用,因为宝石实际上依赖于其全球定义的类; 因此,取消定义课程打破了宝石.当然,gem有多个文件,单独要求将其文件放入模块似乎是一个非常脆弱的解决方案.目前,我发现的唯一解决方法是:
begin
# Require the faulty gem.
require 'rbtagger'
rescue
# If syntactic sugar is enabled...
if NAT.edulcorated?
# Temporarily remove the sugar for the clashing class.
Object.const_unset(:Word); retry
else; raise; end
ensure
# Restore syntactic sugar for the clashing class.
if NAT.edulcorated?
Object.const_set(:Word, NAT::Entities::Word)
end
end
Run Code Online (Sandbox Code Playgroud)
我不知道为什么,但这让我的脚趾甲卷曲.有人有更好的解决方案吗?
另一个可能更好的答案来自这个问题.
利用类和模块只是对象的事实,如下所示:
require 'unsafe_gem'
namespaced_word = Word
Word = nil
# now we can use namespaced_word to refer to the Word class from 'unsafe_gem'
#now your own code
class Word
#awesome code
end
Run Code Online (Sandbox Code Playgroud)
你必须确保unsafe_gem只定义一个类,并require在定义自己的类和模块之前定义它,这样你就不会意外地设置自己的东西nil.
| 归档时间: |
|
| 查看次数: |
3256 次 |
| 最近记录: |