Existe-t-il un moyen plus court d’exiger un fichier dans le même répertoire dans Ruby?

Existe-t-il un moyen plus court d’exiger un fichier situé dans le même répertoire (que le script en cours d’exécution)?

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

J’ai lu que require "my_script" et require "./my_script" chargera le script deux fois (ruby ne reconnaîtra pas qu’il s’agit du même script), et c’est pourquoi File.expand_path est recommandé: s’il est utilisé chaque fois que le script est requirejs, il ne sera chargé qu’une seule fois.

Il me semble étrange qu’un langage concis comme Ruby ne semble pas avoir de solution plus courte. Par exemple, Python a simplement ceci:

 import .some_other_module_in_the_same_directory 

Je suppose que je pourrais require patch-singe … mais ce n’est que du mal! 😉

Depuis Ruby 1.9, vous pouvez utiliser require_relative .

Juste besoin de filename de filename .

Oui, il l’importera deux fois si vous le spécifiez comme filename de filename et ./filename , alors ne le faites pas. Vous ne spécifiez pas le .rb , alors ne spécifiez pas le chemin. Je mets généralement le gros de ma logique applicative dans un fichier de lib , puis j’ai un script dans bin qui ressemble à ceci:

 #!/usr/bin/env ruby $: << File.join(File.dirname(__FILE__), "/../lib") require 'app.rb' App.new.run(ARGV) 

Un autre avantage est que je trouve plus facile de faire des tests unitaires si le chargement de la logique de l'application ne commence pas automatiquement à l'exécuter.

Ce qui précède fonctionnera même lorsque vous exécutez le script depuis un autre répertoire. Cependant, dans le même répertoire, les formulaires plus courts que vous appelez fonctionnent comme prévu et au moins pour Ruby 1.9 ne donneront pas lieu à une double demande.

testa.rb

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

testb.rb

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

en cours d’exécution ‘ruby testa.rb’ se traduira par:

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

Cependant, le formulaire plus long fonctionnera même depuis un autre répertoire (par exemple, ruby ​​somedir / script.rb)

Mettez ceci dans un répertoire de bibliothèque standard (quelque part qui est déjà dans votre chemin $: chargement par défaut $: :):

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

Ensuite, cela devrait fonctionner

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

caller vous donne access à la stack d'appels en cours, vous indique quel fichier et où, alors push-loadpath.rb utilise pour append le fichier qui le load au chemin de chargement.

Notez que vous devez load le fichier plutôt que de l' require , afin que le corps puisse être appelé plusieurs fois (une fois pour chaque fois que vous souhaitez modifier le chemin de chargement).

Alternativement, vous pouvez envelopper le corps dans une méthode,

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

Cela vous permettrait de l' require et de l'utiliser de cette manière:

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