Rubyプログラムで必須パスを管理する最良の方法は何ですか?
基本的な例を挙げましょう。次のような構造を考えてみましょう。
_\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'
以前のバージョンでこれが必要な場合は、拡張ジェムから this SOコメント に従って取得できます。
これを行うには少し変更した方法を次に示します。
$LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), "..", "src"))
ソースへのパスを$ LOAD_PATH(別名$ :)の前に付けることで、コードが必要な場合にルートなどを明示的に指定する必要がありません。つまり、require 'myclass'
同じ、騒々しくない私見:
$:.unshift File.expand_path("../../src", __FILE__)
require 'myclass'
あるいは単に
require File.expand_path "../../src/myclass", __FILE__
(Debian)LinuxでRuby 1.8.7および1.9.0でテスト済み-Windowsでも動作するかどうか教えてください。
なぜもっと単純なメソッド(たとえば、「use」、「require_relative」、またはこのようなsg)が標準libに組み込まれていないのですか?更新:require_relativeは1.9.x以降にあります
Pathname(__FILE__).dirname.realpath
動的な方法で絶対パスを提供します。
次のコードを使用して、特定のフォルダー(=> Ruby 1.9)内のすべての「rb」ファイルを要求します:
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の答えは標準的なアプローチです。
もう1つの方法は、コードをgemとしてパッケージ化することです。次に、rubygemsがライブラリファイルがパスにあることを確認します。
これは私が結んだものです-a Ruby setenv
シェルスクリプトのバージョン:
# 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
次に、このスクリプトが他の何よりも先に呼び出されることを確認する必要があります。個々のソースファイルを変更する必要はありません。
外部(gem以外)ライブラリの場所など、いくつかのオプションを構成ファイル内に配置します。
# Site- and server specific config - location of DB, tmp files etc.
{
:webRoot => "/srv/www/myapp/data",
:rubyLib => "/somewhere/lib",
:tmpDir => "/tmp/myapp"
}
これは私にとってはうまく機能しており、設定ファイルのパラメーターを変更するだけで、複数のプロジェクトでsetenvスクリプトを再利用できます。シェルスクリプトよりもはるかに優れたIMO。