Agregar un directorio a $ LOAD_PATH (Ruby)

He visto dos técnicas de uso común para agregar el directorio del archivo que se está ejecutando actualmente al $ LOAD_PATH (o $ :). Veo las ventajas de hacer esto en caso de que no estés trabajando con una gem. Uno parece más detallado que el otro, obviamente, pero ¿hay alguna razón para ir uno sobre el otro?

El primer método detallado (podría ser excesivo):

$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__))) unless $LOAD_PATH.include?(File.expand_path(File.dirname(__FILE__))) 

y el más directo, rápido y sucio:

 $:.unshift File.dirname(__FILE__) 

¿Alguna razón para ir con uno sobre el otro?

Yo diría que vaya con $:.unshift File.dirname(__FILE__) sobre el otro, simplemente porque he visto mucho más uso de él en el código que el $LOAD_PATH , ¡y también es más corto!

La ruta de carga de Ruby se ve comúnmente escrito como $: pero solo porque es corto, no lo hace mejor. Si prefieres la claridad a la astucia, o si la brevedad por sí misma te produce comezón, no necesitas hacerlo solo porque todos los demás lo son. Decir hola a …

 $LOAD_PATH 

… y decir adiós a …

 # I don't quite understand what this is doing... $: 

No soy muy aficionado a la manera “rápida y sucia”. Cualquier persona nueva en Ruby reflexionará sobre qué $:. es.

Encuentro esto más obvio.

 libdir = File.dirname(__FILE__) $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir) 

O si me importa tener el camino completo …

 libdir = File.expand_path(File.dirname(__FILE__)) $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir) 

ACTUALIZACIÓN 2009/09/10

Últimamente he estado haciendo lo siguiente:

 $:.unshift(File.expand_path(File.dirname(__FILE__))) unless $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__))) 

Lo he visto en un montón de diferentes proyectos de Rubyes mientras navegaba en GitHub.

Parece ser la convención?

Si escribe script/console en su proyecto Rails e ingresa $: obtendrá una matriz que incluye todos los directorios necesarios para cargar Ruby. La conclusión de este pequeño ejercicio es que $: es una matriz. Siendo así, puede realizar funciones en él como anteponer otros directorios con el método de unshift o el operador < < . Como dijiste en tu statement $: y $LOAD_PATH son lo mismo.

La desventaja de hacerlo de manera rápida y sucia como lo mencionó es esto: si ya tiene el directorio en su ruta de arranque, se repetirá.

Ejemplo:

Tengo un complemento que creé llamado todo. Mi directorio está estructurado así:

 /---vendedor
   |
   | --- / plugins
         |
         | --- / todo
               |
               | --- / lib
                     |
                     | --- / app
                           |
                           | --- / modelos
                           | --- / controladores
               |
               | --- / carriles
                     |
                     | --- init.rb

En el archivo init.rb ingresé el siguiente código:

 ## In vendor/plugins/todo/rails/init.rb %w{ models controllers models }.each do |dir| path = File.expand_path(File.join(File.dirname(__FILE__), '../lib', 'app', dir)) $LOAD_PATH < < path ActiveSupport::Dependencies.load_paths << path ActiveSupport::Dependencies.load_once_paths.delete(path) end 

Fíjese cómo le digo al bloque de códigos que realice las acciones dentro del bloque para las cadenas 'modelos', 'controladores' y 'modelos', donde repito 'modelos'. (FYI, %w{ ... } es solo otra forma de decirle a Ruby que mantenga una serie de cadenas). Cuando ejecuto script/console , escribo lo siguiente:

 >> puts $: 

Y escribo esto para que sea más fácil leer el contenido de la cadena. El resultado que obtengo es:

 ...
 ...
 ./Users/Me/mySites/myRailsApp/vendor/plugins/todo/lib/app/models
 ./Users/Me/mySites/myRailsApp/vendor/plugins/todo/lib/app/controllers
 ./Users/Me/mySites/myRailsApp/vendor/plugins/todo/lib/app/models

Como puede ver, aunque este es un ejemplo tan simple que podría crear al usar un proyecto en el que estoy trabajando actualmente, si no tiene cuidado, el camino rápido y sucio dará lugar a caminos repetidos. La forma más larga verificará las rutas repetidas y se asegurará de que no ocurran.

Si eres un experimentado progtwigdor de Rails, probablemente tengas una muy buena idea de lo que estás haciendo y probablemente no cometas el error de repetir los caminos. Si eres un novato, iría por el camino más largo hasta que entiendas realmente lo que estás haciendo.

Lo mejor que he encontrado para agregar un directorio a través de una ruta relativa cuando uso Rspec. Me parece lo suficientemente detallado, pero también sigue siendo un buen trazador de líneas.

 $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib')) 

Hay una gem que le permitirá configurar su ruta de carga con un código más limpio y más limpio. Mira esto: https://github.com/nayyara-samuel/load-path .

También tiene buena documentación