什么`if __FILE__ == $ 0`在Ruby中意味着什么

时间:2011-01-14 03:21:25

标签: ruby

if __FILE__ == $0
  $:.unshift File.join(File.dirname(__FILE__),'..')

我在Ruby中找到了这个代码,这是什么意思?

6 个答案:

答案 0 :(得分:52)

# Only run the following code when this file is the main file being run
# instead of having been required or loaded by another file
if __FILE__==$0
  # Find the parent directory of this file and add it to the front
  # of the list of locations to look in when using require
  $:.unshift File.expand_path("../../", __FILE__)  
end

请注意,require_relative的出现通常不需要这种特殊做法(添加到LOAD_PATH目录),而expand_path是查找父目录的更简单方法。

答案 1 :(得分:34)

这是一些Ruby Mini-Design-Patterns

这意味着:

  • 如果文件正在直接执行,即作为脚本,
  • 然后找到脚本所在的目录,并将其添加到load / require搜索路径的开头

条件部分可用于许多事情。可以编写Ruby文件以提供大型程序的功能,但也可以(使用额外的代码)作为脚本。或者,脚本表单可以运行模块的测试,而组件表单为更大的程序实现一些类,并且仅在通过名称引用时调用测试。

路径前置有一些一般用途,除了显而易见的查找私有包含。如果你有几个不同的版本或版本的东西,这样任何伴侣“可执行文件”(脚本)将被优先调用。 / usr / local / release232 / bin /无论从哪个bin目录运行所有内容,即使release220在默认路径上更早。

答案 2 :(得分:14)

关于ruby-lang.org的内容/原因的一个很好的解释:

  

__FILE__是包含当前文件名称的魔术变量。 $0是用于启动程序的文件的名称。   此检查显示“如果这是正在使用的主文件...”这允许将文件用作库,而不是在该上下文中执行代码,但如果该文件用作可执行文件,然后执行该代码。

请参阅:https://www.ruby-lang.org/en/documentation/quickstart/4/

答案 3 :(得分:9)

Ruby与任何语言一样,都有一些保留的关键字,包括ifreturnclass;其中一个恰好是__FILE__。 Ruby使用__FILE__来保存当前的源文件名。

变量名称的前缀$表示全局变量。在这种情况下,$0包含正在执行的脚本的名称。例如,如果您运行ruby hello_world.rb,则$0的值为hello_world.rb

if __FILE__ == $0
  ...
end

现在if语句中的代码只有在包含源代码的文件与您正在执行的文件相同时才会执行。为了更好地解释,我们创建2个文件。

首先hello_world.rb

# hello_world

puts "Hello world"

和第二个hello_pluto.rb

# hello_pluto

require_relative "hello_world"
puts "Hello Pluto"

如果你运行ruby hello_world.rb,它只会输出:

Hello world

现在,如果您运行ruby hello_pluto.rb,它将输出:

Hello world
Hello Pluto

它实际上也运行文件hello_world。现在将来自hello_world的代码粘贴到if语句中并再次运行hello_pluto:

# hello_world

if __FILE__ == $0
  puts "Hello world"
end

正如预期的那样,您唯一看到的是Hello Pluto。因此,if语句保证语句中的任何代码只有在源文件与您运行的脚本相同时才会运行。

参考:http://periclestheo.com/2014/02/what-is-up-with-FILE-and- $ 0.html

答案 4 :(得分:6)

我建议您在$PROGRAM_NAME上使用$0别名,因为当您使用它时,您的意思会更清楚一点 - 它们的意思相同。

现在,$PROGRAM_NAME / $0是什么意思? From the Ruby docs

  

<强> $ 0
  包含正在执行的脚本的名称。可以分配。

让我们演示一下如何使用代码。

1。创建hello.rb

module Hello
  def self.world
    puts "Hello, world!"
    puts "$0       = #{$0}"
    puts "__FILE__ = #{__FILE__}"
  end
end

if $PROGRAM_NAME == __FILE__
  puts Hello.world
end

看看如果你自己运行这个文件会发生什么:

$ ruby hello.rb
Hello, world!
$0       = hello.rb
__FILE__ = hello.rb

2。创建一个Rakefile

require 'rake'
require_relative 'hello'

task :hello do
  Hello.world
end

现在在Rake任务的上下文中执行相同的代码:

$ rake hello
Hello, world!
$0       = /Users/sean/.rbenv/versions/2.3.0/bin/rake
__FILE__ = /Users/sean/Projects/hello/hello.rb

if $PROGRAM_NAME == __FILE__条件的Ruby文件末尾包装代码是许多开发人员用来说“只有在你单独运行这个文件时才执行此代码”的习惯用法。

你会在这个条件中包装什么样的代码?我经常用它来演示如何使用模块。这也使得单独执行此文件非常方便,以确保它在您可能正在编写的较大程序的上下文之外工作。

如果你没有将你的示例代码包装在这个条件中,那么只要在你的大型程序的生命周期中需要/加载文件就会执行它,这几乎肯定不是你想要的。

答案 5 :(得分:5)

这意味着如果文件直接运行,不需要或加载,则将脚本父目录添加到$ LOAD_PATH(ruby搜索需要的文件的路径()d)