Ответ 1
С Ruby 1.9 вы можете использовать require_relative для этого:
require_relative '../src/myclass'
Если вам это нужно для более ранних версий, вы можете получить его из gems расширения по этому комментарию SO.
Каков наилучший способ управления требуемыми путями в рубиновой программе?
Позвольте мне привести базовый пример, рассмотрим структуру типа:
\MyProgram
\MyProgram\src\myclass.rb
\MyProgram\test\mytest.rb
Если в моем тесте я использую require '../src/myclass'
, тогда я могу только вызывать тест из папки \MyProgram\test
, но я хочу иметь возможность называть его по любому пути!
Решение, с которым я столкнулся, - это определить во всех исходных файлах следующую строку:
ROOT = "#{File.dirname(__FILE__)}/.." unless defined?(ROOT)
, а затем всегда используйте require "#{ROOT}/src/myclass"
Есть ли лучший способ сделать это?
С Ruby 1.9 вы можете использовать require_relative для этого:
require_relative '../src/myclass'
Если вам это нужно для более ранних версий, вы можете получить его из gems расширения по этому комментарию SO.
Вот несколько измененный способ сделать это:
$LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), "..", "src"))
Добавив путь к вашему источнику в $LOAD_PATH (aka $:), вам не нужно указывать корень и т.д. явно, когда вам нужен ваш код, т.е. require 'myclass'
То же самое, менее шумное ИМХО:
$:.unshift File.expand_path("../../src", __FILE__)
require 'myclass'
или просто
require File.expand_path "../../src/myclass", __FILE__
Протестировано с рубином 1.8.7 и 1.9.0 на (Debian) Linux - скажите, пожалуйста, работает ли он и в Windows.
Почему более простой метод (например, 'use', 'require_relative' или sg как это) не встроен в стандартную lib? UPDATE: require_relative существует с 1.9.x
Pathname(__FILE__).dirname.realpath
обеспечивает абсолютный путь динамическим способом.
Используйте следующий код, чтобы потребовать все файлы "rb" в определенной папке (= > Ruby 1.9):
path='../specific_folder/' # relative path from current file to required folder
Dir[File.dirname(__FILE__) + '/'+path+'*.rb'].each do |file|
require_relative path+File.basename(file) # require all files with .rb extension in this folder
end
Ответ sris - стандартный подход.
Другой способ - упаковать ваш код в качестве драгоценного камня. Затем rubygems позаботятся о том, чтобы ваши файлы библиотеки находились на вашем пути.
Это то, что я закончил - Ruby-версия оболочки setenv
script:
# Read application config
$hConf, $fConf = {}, File.expand_path("../config.rb", __FILE__)
$hConf = File.open($fConf) {|f| eval(f.read)} if File.exist? $fConf
# Application classpath
$: << ($hConf[:appRoot] || File.expand_path("../bin/app", __FILE__))
# Ruby libs
$lib = ($hConf[:rubyLib] || File.expand_path("../bin/lib", __FILE__))
($: << [$lib]).flatten! # lib is string or array, standardize
Тогда мне просто нужно убедиться, что этот script вызывается один раз перед чем-то другим и не нужно касаться отдельных исходных файлов.
Я помещаю некоторые параметры внутри файла конфигурации, например, расположение внешних (не-gem) библиотек:
# Site- and server specific config - location of DB, tmp files etc.
{
:webRoot => "/srv/www/myapp/data",
:rubyLib => "/somewhere/lib",
:tmpDir => "/tmp/myapp"
}
Это хорошо работает для меня, и я могу повторно использовать setenv script в нескольких проектах, просто изменив параметры в файле конфигурации. Гораздо лучшая альтернатива, чем shell-скрипты, IMO.