【发布时间】:2011-01-14 03:21:24
【问题描述】:
if __FILE__ == $0
$:.unshift File.join(File.dirname(__FILE__),'..')
我在Ruby中找到了这段代码,这是什么意思?
【问题讨论】:
标签: ruby
if __FILE__ == $0
$:.unshift File.join(File.dirname(__FILE__),'..')
我在Ruby中找到了这段代码,这是什么意思?
【问题讨论】:
标签: ruby
# 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 是一种更简单的查找父目录的方法。
【讨论】:
__FILE__:这个文件名,$0:运行的主文件,$::LOAD_PATH
意思是:
条件部分可以用于许多事情。可以编写 Ruby 文件来为大型程序提供功能,但也可以(使用额外代码)作为脚本使用。或者,脚本表单可以运行模块的测试,而组件表单为更大的程序实现一些类,并且只有在名称引用时才调用测试。
路径前缀有一些一般用途,除了寻找私有包含的明显用途。如果您有几个不同的版本或版本,那么任何伴随的“可执行文件”(脚本)都会被优先调用。 /usr/local/release232/bin/whatever 将从同一个 bin 目录运行所有内容,即使 release220 在默认路径上更早。
【讨论】:
关于什么/为什么来自 ruby-lang.org 的一个很好的解释:
__FILE__是包含当前文件名称的魔法变量。$0是用于启动程序的文件名。 此检查显示“如果这是正在使用的主文件……” 这允许将文件用作库,而不是在该上下文中执行代码,但如果文件被用作可执行文件,然后执行该代码。
【讨论】:
Ruby 和任何语言一样,有一些保留关键字,包括if、return、class;其中之一恰好是__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
【讨论】:
我建议您使用 $PROGRAM_NAME 别名而不是 $0,因为使用它时您的意思会更清楚一些——它们的意思是一样的。
现在,$PROGRAM_NAME/$0 是什么意思? From the Ruby docs:
$0
包含正在执行的脚本的名称。可能是可分配的。
让我们用代码演示一下它是如何工作的。
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
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 文件的末尾是许多开发人员用来说“仅在单独运行此文件时才执行此代码”的习惯用法。
你会在这个条件中包装什么样的代码?我经常用它来演示如何使用一个模块。这也使得单独执行此文件非常方便,以确保它在您可能正在编写的较大程序的上下文之外工作。
如果您没有将示例代码包装在此条件中,那么只要在较大程序的生命周期中需要/加载文件时就会执行它,这几乎肯定不是您想要的。
【讨论】:
这意味着如果文件是直接运行的,不需要或加载,则将脚本父目录添加到 $LOAD_PATH(ruby 搜索需要()d 文件的路径)
【讨论】: