2009-04-25 14 views
51

¿Hay alguna manera más corta de requerir un archivo ubicado en el mismo directorio (como el script que se está ejecutando)?¿Hay alguna manera más corta de requerir un archivo en el mismo directorio en ruby?

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

leí que require "my_script" y require "./my_script" realmente cargar el guión doble (rubí no reconocerá que en realidad es el mismo guión), y esta es la razón por la cual se recomienda File.expand_path: si se utiliza cada vez que el se requiere una secuencia de comandos, luego solo se cargará una vez.

Me parece extraño que un lenguaje conciso como Ruby no parezca tener una solución más corta. Por ejemplo, pitón tiene simplemente esto:

import .some_other_module_in_the_same_directory 

supongo que pude mono-parche require ... pero eso es sólo el mal! ;-)

Respuesta

2

Lo anterior funcionará incluso cuando ejecute el script desde otro directorio. Sin embargo, dentro del mismo directorio, los formularios más cortos a los que se refiere funcionan como se espera y al menos para ruby ​​1.9 no darán como resultado un doble requerimiento.

testa.rb

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

testb.rb

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

correr 'testa.rb rubí' dará lugar a:

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

Sin embargo, la forma más larga funcionará incluso desde otro directorio (ej. ruby ​​somedir/script.rb)

2

poner esto en un directorio de la biblioteca estándar (en algún lugar que ya está en su LOADPATH predeterminado $:):

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

Entonces, esto debería funcionar

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

caller le da acceso a la pila de llamadas actual, y le dice qué archivo y dónde, por lo que push-loadpath.rb lo usa para agregar el archivo que load 'd a la ruta de carga.

Tenga en cuenta que debe load el archivo, en lugar de require, por lo que el cuerpo se puede invocar varias veces (una vez por cada vez que desee modificar la ruta de carga).

Como alternativa, podría envolver el cuerpo en un método,

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

Esto le permitiría a require, y usarlo de esta manera:

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

sólo requieren filename.

Sí, lo importará dos veces si lo especifica como filename y ./filename, entonces no lo haga. No especifica el .rb, por lo tanto, no especifique la ruta.Yo suelo poner la mayor parte de mi lógica de la aplicación en un archivo en lib, y luego tener un guión en bin que se ve algo como esto:

#!/usr/bin/env ruby 

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

Otra ventaja es que se me hace más fácil hacer las pruebas unitarias si la carga la lógica de la aplicación no comienza a ejecutarlo automáticamente.

83

Desde ruby ​​1.9 puede usar require_relative.

+0

Oh Dios, ojalá haya visto tu respuesta antes. –

Cuestiones relacionadas