为什么`require_relative`工作但`require`不工作?

时间:2016-06-21 06:32:40

标签: ruby-on-rails ruby

通过"良好的基础Rubyist"本书和一些代码示例让您使用require来加载文件。不幸的是,在使用require "stacklike"时,我收到此错误"/home/userP/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:55:in 'require': cannot load such file -- stacklike (LoadError)"

使用require_relative "stacklike"效果很好。为什么这样做,但不是require

2 个答案:

答案 0 :(得分:1)

这是因为class ActorA extends Actor{ override val supervisorStrategy = OneForOneStrategy( maxNrOfRetries = 10, withinTimeRange = 10 seconds) { case _:AskTimeoutException => ??? (Resume/Restart) case _:Exception => Restart } val actorB =context.actorof ...//actor creation code implicit val timeout = Timeout(interval , SECONDS) val future = ask(actorB, MessageB).mapTo[Boolean] //what if actorB does not reply withing the time and AskTimeoutException is thrown the what should be the supervision strategy var response = Await.result(future, timeout.duration) } 是相对于工作目录(和库搜索路径)和" stacklike.rb"与您要求的文件位于同一目录中,而不是在您的工作目录中。

您可以将stacklike.rb移动到您的工作目录 - 或者甚至更好地继续使用require - 它没有任何问题。它甚至更好 - 因为当你阅读文件时,你确切知道它应该在哪里。

答案 1 :(得分:1)

require搜索要加载到$LOAD_PATH的文件。 require_relative搜索相对于文件所在目录的文件,即require_relative的调用所在的文件。两者完全不同。

require './stacklike'将在当前工作目录中查找该文件。这是一个非常糟糕的主意:如果您的脚本位于/home/ordek/myproject/bin/myscript.rb且您位于/home/ordek/myproject并将其称为ruby bin/myscript.rb,则当前工作目录为/home/ordek/myproject和{{ 1}}将查找文件require './stacklike'。如果您在/home/ordek/myproject/stacklike.rb并将其称为/home/ordek/myproject/bin,那么您当前的工作目录为./myscript.rb/home/ordek/myproject/bin将查找文件require './stacklike'

换句话说:加载哪个文件取决于脚本控制之外的环境(毕竟,你的脚本不能从它的调用位置影响),这是不好的(至少可以说)。事实上,它可以允许攻击者将自己的代码注入到您的脚本中,这可能是灾难性的。

因此,在加载文件时,永远不会依赖当前的工作目录。

根据您的情况,/home/ordek/myproject/bin/stacklike.rb唯一的正确选择。