如何临时更改 Ruby 中的 require 路径 ($:)?
我正在为一个复杂的项目使用一堆 Rake 任务做一些技巧,逐渐地一次重构一些块的复杂性。这暴露了前项目维护者留下的奇怪的依赖网络。
我想要做的是将项目中的特定路径添加到 require
的要搜索的路径列表中,即 $:
。但是,我只希望在一个特定方法的上下文中搜索该路径。现在我正在做这样的事情:
def foo()
# Look up old paths, add new special path.
paths = $:
$: << special_path
# Do work ...
bar()
baz()
quux()
# Reset.
$:.clear
$: << paths
end
def bar()
require '...' # If called from within foo(), will also search special_path.
...
end
这显然是一个可怕的黑客行为。有更好的办法吗?
I'm doing some trickery with a bunch of Rake tasks for a complex project, gradually refactoring away some of the complexity in chunks at a time. This has exposed the bizarre web of dependencies left behind by the previous project maintainer.
What I'd like to be able to do is to add a specific path in the project to require
's list of paths to be searched, aka $:
. However, I only want that path to be searched in the context of one particular method. Right now I'm doing something like this:
def foo()
# Look up old paths, add new special path.
paths = $:
$: << special_path
# Do work ...
bar()
baz()
quux()
# Reset.
$:.clear
$: << paths
end
def bar()
require '...' # If called from within foo(), will also search special_path.
...
end
This is clearly a monstrous hack. Is there a better way?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
由于
$:
是一个数组,因此您必须小心您所做的事情。您需要获取一份副本(通过dup
)并稍后替换
。不过,简单地删除您添加的内容更简单:如果没有更多信息,很难知道是否有更好的方法。
Since
$:
is an Array, you have to be careful about what you are doing. You need to take a copy (viadup
) andreplace
it later. It' simpler to simply remove what you have added, though:Without more info, it's difficult to know if there is a better way.
require
实际上是一个方法,它是Kernel#require
(它调用rb_require_safe
),所以你至少可以在猴子补丁版本中执行你的黑客攻击。如果你喜欢这样的事情。只是为了好玩,我对此进行了快速的抨击,原型如下。这尚未经过充分测试,我还没有检查
rb_require_safe
的语义,您可能还需要查看#load
和#includeKernel
模块的猴子补丁。这也许并不完全是可怕的,但它肯定是一种黑客行为。您的电话是否比弄乱全局$:
变量更好或更坏。示例:
require
is actually a method, it'sKernel#require
(which callsrb_require_safe
) so you could at least perform your hackery in a monkey-patched version. If you like that kind of thing.Just for fun I had a quick bash at that, prototype is below. This isn't fully tested, I haven't checked the semantics of
rb_require_safe
, and you probably would also need to look at#load
and#include
for completeness -- and this remains a monkey-patch of theKernel
module. It's perhaps not entirely monstrous, but it's certainly a hack. Your call if it's better or worse than messing with the global$:
variable.Examples: