如果没有宝石作者的合作,这是不可能的。
当你require
创建一个文件时,文件中的代码就会运行。时期。如果文件猴子补丁中的代码修改了一个类或修改了全局命名空间或其他任何东西,那将会发生。时期。
您可以使用它load
来代替require
允许您在匿名模块的上下文中评估文件。但是,当然,使用命名空间运算符::
,文件中的代码仍然可以访问全局命名空间以及其中的每个模块和类,只需执行类似class ::String; def length; 42 end end
.
现在,如果 gem 作者将他的 gem 作为refine
ment 发布,那么您至少可以将效果限制为单个脚本主体:
string_with_upper_reverse.rb
:
module UpperReverse
def reverse
super.upcase
end
end
module StringWithUpperReverse
refine String do
prepend UpperReverse
end
end
puts 'Hello'.reverse
# olleH
using StringWithUpperReverse
puts 'Hello'.reverse
# OLLEH
test.rb
:
puts 'Hello'.reverse
# olleH
require_relative 'string_with_upper_reverse'
puts 'Hello'.reverse
# olleH
using StringWithUpperReverse
puts 'Hello'.reverse
# OLLEH
require_relative 'required'
required.rb
:
puts 'Hello'.reverse
# olleH
using StringWithUpperReverse
puts 'Hello'.reverse
# OLLEH
如您所见,ment 的脚本既不require
ing 也不被require
d意味着该using
ment在您的脚本中可见。只有在脚本主体内显式的ment 才会使该ment仅从该点开始且仅在该脚本主体内可见。refine
refine
using
refine
refine
但是请注意,refine
ment 是一个实验性功能:它们的 API 可能会在未来的 Ruby 版本中更改,恕不另行通知,它们甚至可能被完全删除。
另请注意refine
,Ruby 2.0.0 附带的 ments 版本(以及 Ruby 2.1 的当前开发版本)只能作用于脚本主体。在 Ruby 2.0.0 发布前不久,范围module
和主体的能力连同方法一起被删除。class
Module#using
最后,请注意Object#send
忽略refine
ments:
require_relative 'string_with_upper_reverse'
using StringWithUpperReverse
puts 'Hello'.reverse
# OLLEH
puts 'Hello'.send(:reverse)
# olleH