我需要一行可以执行以下操作的代码:
skewY
但对于多个文件......这不起作用:
instance_eval(IO.read(File.expand_path('../../policyfiles/base.rb', __FILE__)))
关于如何做到这一点的任何想法?
答案 0 :(得分:1)
如果您有一个列表并希望对每个元素执行操作,请使用each
。
policy_files = ['../../policyfiles/base.rb', '../../policyfiles/app.rb']
policy_files.each { |file|
instance_eval(IO.read(File.expand_path(file, __FILE__)))
}
但是应该避免裸instance_eval
。它将加载这些文件的内容,就像它们在当前范围内一样。任何全局变量都会超越你自己和彼此。例如......
$ cat policy.rb
foo = 42
def bar
99
end
$ cat test.rb
foo = 23
instance_eval(IO.read("policy.rb"))
puts foo
puts bar
$ ruby ~/tmp/test.rb
42
99
因为instance_eval
在test.rb的范围内运行test2.rb的内容,包括foo = 42
。惊喜!
而是使用require_relative。这是加载相对文件的工作,但它不会混淆全局变量。你只会得到方法。
policy_files.each { |file|
require_relative(file)
}
现在当我们做同样的事情,但是require_relative
,你的全局变量是安全的。
$ cat policy.rb
foo = 42
def bar
99
end
$ cat test.rb
foo = 23
require_relative("policy.rb")
puts foo
puts bar
$ ruby ~/tmp/test.rb
23
99
现在,策略文件中的全局变量不会破坏调用者。
require_relative
还有一个额外的好处,就是它只会加载一个一次的给定文件。这意味着任何代码都可以安全地加载这些文件,而无需考虑是否已经加载了其他文件。
请注意,策略的用户必须加载基本策略似乎很奇怪。我不能肯定地说不知道这些文件是做什么的,但我怀疑app.rb应该处理加载base.rb。
另请注意,使用相对路径可能不是最好的选择。如果你重新组织你的代码文件,他们都会破坏。相反,consider adding the top level library directory to $LOAD_PATH。
lib_dir = ...whatever you need to figure this out...
$LOAD_PATH.unshift(lib_dir)
然后,假设policyfiles/
位于库树的顶部,您可以从项目中的任何文件中require("policyfiles/app.rb")
,无论其位置如何。