我需要一行代码,可以这样做:
instance_eval(IO.read(File.expand_path('../../policyfiles/base.rb', __FILE__)))但对于多个文件..。这样做是行不通的:
instance_eval(IO.read(File.expand_path('../../policyfiles/base.rb', '../../policyfiles/app.rb', __FILE__)))知道怎么做吗?
发布于 2017-07-10 21:15:40
如果您有一个列表,并且希望对每个元素执行操作,请使用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。惊喜吧!
相反,请使用相对的。这将完成加载相关文件的工作,但不会混淆全局文件。你只会得到方法。
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现在,策略文件中的globals不能干扰调用者。
require_relative的另一个优点是它只加载一次给定的文件。这意味着,任何代码都可以安全地加载这些文件,而无需考虑其他东西是否已经加载了它们。
注意,似乎奇怪的是,策略的用户必须加载基本策略。在不知道这些文件做什么的情况下,我不能肯定地说,但是我怀疑app.rb应该处理加载base.rb。
还请注意,使用相对路径可能不是最好的做法。如果您重新组织您的代码文件,它们都会崩溃。相反,路径。
lib_dir = ...whatever you need to figure this out...
$LOAD_PATH.unshift(lib_dir)然后,假设policyfiles/位于库树的顶部,那么您可以从项目中的任何文件中获取require("policyfiles/app.rb"),无论其位置如何。
https://stackoverflow.com/questions/45021219
复制相似问题