una soy rubi pedagoga menstrual menstruacion loca estoy escuela erika cíclica cuatro ciclica blog ruby relative-path

ruby - soy - Gestión del camino rubí



no soy una soy cuatro erika (7)

¿Cuál es la mejor manera de administrar las rutas requeridas en un programa ruby?

Permítanme darles un ejemplo básico, consideren una estructura como:

/MyProgram /MyProgram/src/myclass.rb /MyProgram/test/mytest.rb

Si en mi prueba utilizo require ''../src/myclass'' entonces solo puedo llamar a la prueba desde la /MyProgram/test , ¡pero quiero poder llamar desde cualquier ruta!

La solución que se me ocurrió es definir en todos los archivos de origen la siguiente línea:

ROOT = "#{File.dirname(__FILE__)}/.." unless defined?(ROOT) y luego siempre use require "#{ROOT}/src/myclass"

Hay una mejor manera de hacerlo?


A partir de Ruby 1.9 puede usar require_relative para hacer esto:

require_relative ''../src/myclass''

Si necesita esto para versiones anteriores, puede obtenerlo de la gema de extensiones según este comentario SO .


Aquí hay una forma ligeramente modificada de hacerlo:

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

Al añadir la ruta a su fuente a $ LOAD_PATH (aka $ :), no tiene que proporcionar la raíz, etc. explícitamente cuando necesita su código, es decir, require ''myclass''


Esto es lo que terminé con - una versión Ruby de un script de shell 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

Entonces, solo necesito asegurarme de que esta secuencia de comandos se llame una vez antes que de cualquier otra cosa, y no necesito tocar los archivos de origen individuales.

Puse algunas opciones dentro de un archivo de configuración, como la ubicación de las bibliotecas externas (que no son gemas):

# Site- and server specific config - location of DB, tmp files etc. { :webRoot => "/srv/www/myapp/data", :rubyLib => "/somewhere/lib", :tmpDir => "/tmp/myapp" }

Esto me ha funcionado bien y puedo reutilizar el script setenv en varios proyectos simplemente cambiando los parámetros en el archivo de configuración. Una alternativa mucho mejor que los scripts de shell, IMO.


La misma, menos ruidoso IMHO:

$:.unshift File.expand_path("../../src", __FILE__) require ''myclass''

o solo

require File.expand_path "../../src/myclass", __FILE__

Probado con ruby ​​1.8.7 y 1.9.0 en (Debian) Linux, dime si funciona también en Windows.

¿Por qué un método más simple (por ejemplo, ''use'', ''require_relative'' o sg como este) no está incorporado en la biblioteca estándar? ACTUALIZACIÓN: require_relative está ahí desde 1.9.x


La respuesta de Sris es el enfoque estándar.

Otra forma sería empaquetar su código como una gema. Luego rubygems se encargará de asegurarse de que los archivos de su biblioteca estén en su camino.


Use el siguiente código para requerir todos los archivos "rb" en una carpeta específica (=> 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


Pathname(__FILE__).dirname.realpath

Proporciona un camino absoluto de forma dinámica.