Подтвердить что ты не робот

Есть ли более короткий способ потребовать файл в том же каталоге в рубине?

Есть ли более короткий способ потребовать файл, расположенный в той же директории (как выполняется script)?

require File.expand_path(File.dirname(__FILE__) + '/some_other_script')

Я читал, что require "my_script" и require "./my_script" будут дважды загружать script (рубин не признает, что он фактически тот же script), и именно поэтому рекомендуется File.expand_path: if он используется каждый раз, когда требуется script, тогда он будет загружен только один раз.

Мне кажется странным, что краткий язык, такой как Ruby, кажется, не имеет более короткого решения. Например, python просто имеет это:

import .some_other_module_in_the_same_directory

Думаю, я мог бы обезьян-патч require... но это просто зло!; -)

4b9b3361

Ответ 1

С ruby ​​1.9 вы можете использовать require_relative.

Ответ 2

Просто введите filename.

Да, он будет импортировать его дважды, если вы укажете его как filename и ./filename, поэтому не делайте этого. Вы не указываете .rb, поэтому не указываете путь. Я обычно добавляю основную часть моей логики приложения в файл в lib, а затем script в bin выглядит примерно так:

#!/usr/bin/env ruby

$: << File.join(File.dirname(__FILE__), "/../lib")
require 'app.rb'
App.new.run(ARGV)

Еще одно преимущество заключается в том, что мне легче выполнять модульное тестирование, если загрузка логики приложения не запускается автоматически.

Ответ 3

Вышеупомянутое будет работать, даже если вы запускаете script из другого каталога. Однако внутри одного и того же каталога более короткие формы, на которые вы ссылаетесь, работают как ожидалось, и, по крайней мере, для ruby ​​1.9 не приведет к двойному требованию.

testa.rb

puts "start test A"
require 'testb'
require './testb'
puts "finish test A"

testb.rb

puts "start test B"
puts "finish test B"

running 'ruby testa.rb' приведет к:

start test A
start test B
finish test B
finish test A

Однако более длинная форма будет работать даже из другого каталога (например, ruby ​​somedir/ script.rb)

Ответ 4

Поместите это в стандартный каталог библиотеки (где-то уже в пути загрузки по умолчанию $:):

# push-loadpath.rb
if caller.first
  $: << File.expand_path(File.dirname(caller.first))
end

Затем это должно работать

% ls /path/to/
bin.rb lib1.rb lib2.rb #...
% cat /path/to/bin.rb
load 'push-loadpath.rb'
require 'lib1'
require 'lib2'
#...

caller дает вам доступ к текущему столу вызова и сообщает вам, какой файл и где, поэтому push-loadpath.rb использует это, чтобы добавить файл, который load 'd это в путь загрузки.

Обратите внимание, что вы должны load файла, а не require его, чтобы тело можно было вызвать несколько раз (один раз для каждого раза, когда вы хотите изменить путь загрузки).

В качестве альтернативы вы можете обернуть тело методом,

# push-loadpath.rb
def push_loadpath
  $: << File.expand_path(File.dirname(caller.first))
end

Это позволит вам require его и использовать его следующим образом:

% ls /path/to/
bin.rb lib1.rb lib2.rb #...
% cat /path/to/bin.rb
require 'push-loadpath'
push_loadpath
require 'lib1'
require 'lib2'
#...