web-dev-qa-db-ja.com

Rubyパス管理

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"_を使用します

それを行うより良い方法はありますか?

27
Miguel Fonseca

Ruby 1.9以降、 require_relative を使用してこれを行うことができます:

require_relative '../src/myclass'

以前のバージョンでこれが必要な場合は、拡張ジェムから this SOコメント に従って取得できます。

30
David Tchepak

これを行うには少し変更した方法を次に示します。

$LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), "..", "src"))

ソースへのパスを$ LOAD_PATH(別名$ :)の前に付けることで、コードが必要な場合にルートなどを明示的に指定する必要がありません。つまり、require 'myclass'

12
sris

同じ、騒々しくない私見:

$:.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以降にあります

9
inger
Pathname(__FILE__).dirname.realpath

動的な方法で絶対パスを提供します。

2
schwabsauce

次のコードを使用して、特定のフォルダー(=> 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
2
Vadim

srisの答えは標準的なアプローチです。

もう1つの方法は、コードをgemとしてパッケージ化することです。次に、rubygemsがライブラリファイルがパスにあることを確認します。

1
rampion

これは私が結んだものです-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。

0
j-g-faustus