Что означает `if __FILE__ == $ 0` в Ruby - PullRequest
48 голосов
/ 14 января 2011
if __FILE__ == $0
  $:.unshift File.join(File.dirname(__FILE__),'..')

Я нашел этот код в Ruby, в чем смысл?

Ответы [ 6 ]

52 голосов
/ 14 января 2011
# 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

Обратите внимание, что эта конкретная практика (добавление в каталог LOAD_PATH) обычно не требуется с появлением require_relative, а expand_path - более простой способ поиска родительского каталога.

34 голосов
/ 14 января 2011

Это пара Ruby Mini-Design-Patterns

Это означает:

  • ЕСЛИ файл выполняется непосредственно, то есть как скрипт,
  • ТОГДА найдите каталог, в котором находится скрипт, и добавьте его к началу пути поиска load / require

Условная часть может быть полезна для многих вещей.Файл Ruby может быть написан для обеспечения функциональности большой программы, но также доступен (с дополнительным кодом) в виде скрипта.В качестве альтернативы форма скрипта может запускать тесты модуля, в то время как форма компонента реализует некоторый класс для более крупной программы и вызывает тесты, только если на них ссылается имя.один из нахождения частного включает.Если у вас есть несколько разных версий или выпусков чего-либо, таким образом любые сопутствующие «исполняемые файлы» (скрипты) будут вызываться преимущественно./ usr / local / release232 / bin / что угодно запустит все из того же каталога bin, даже если release220 ранее находился в пути по умолчанию.

14 голосов
/ 03 апреля 2015

Отличное объяснение того, что / почему от ruby-lang.org:

__FILE__ - магическая переменная, которая содержит имя текущего файла. $0 - это имя файла, используемого для запуска программы. Эта проверка говорит: «Если это основной файл, который используется…» Это позволяет использовать файл в качестве библиотеки, и не выполнять код в этом контексте, но если файл используется в качестве исполняемого файла затем выполните этот код.

См .: https://www.ruby -lang.org / ru / Documentation / quickstart / 4 /

9 голосов
/ 14 августа 2015

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 гарантирует, что любой код, который находится внутри оператора, будет выполняться только в том случае, если исходный файл совпадает с выполняемым сценарием.

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

6 голосов
/ 08 марта 2016

Я рекомендую вам использовать $PROGRAM_NAME псевдоним над $0, поскольку немного яснее, что вы имеете в виду, когда используете его - они означают одно и то же.

Теперь, что означает $PROGRAM_NAME / $0? Из рубиновых документов :

$ 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. Создать рейкфайл

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

Заключение кода в конец файла Ruby в условном выражении if $PROGRAM_NAME == __FILE__ - это идиома, которую многие разработчики используют, чтобы сказать: «Выполняйте этот код, только если вы запускаете этот файл по отдельности».

Какой код вы бы добавили в это условие? Я часто использую его, чтобы продемонстрировать, как использовать модуль. Это также делает очень удобным выполнение этого файла изолированно, чтобы убедиться, что он работает вне контекста более крупной программы, которую вы, возможно, пишете.

Если вы не заключили пример кода в это условие, то он будет выполняться всякий раз, когда файл требуется / загружается в жизненном цикле вашей более крупной программы, что почти наверняка не то, что вам нужно.

5 голосов
/ 14 января 2011

это означает, что если файл был запущен напрямую, не требуется или загружен, то добавьте родительский каталог скриптов в $ LOAD_PATH (путь, по которому ruby ​​ищет файлы, которые требуют () d)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...