154 votes

Ruby : require vs require_relative - meilleure pratique pour contourner les problèmes de fonctionnement dans Ruby <1.9.2 et >=1.9.2

Quelle est la meilleure pratique si je veux require un fichier relatif en Ruby y Je veux qu'il fonctionne à la fois dans 1.8.x et >=1.9.2 ?

Je vois quelques options :

  • juste faire $LOAD_PATH << '.' et oublier tout

  • faire $LOAD_PATH << File.dirname(__FILE__)

  • require './path/to/file'

  • vérifier si RUBY_VERSION < 1.9.2, alors définir require_relative comme require , utiliser require_relative partout où cela est nécessaire par la suite

  • vérifier si require_relative existe déjà, si c'est le cas, essayer de procéder comme dans le cas précédent

  • utiliser des constructions bizarres telles que`

    require File.join(File.dirname(__FILE__), 'path/to/file')

    `- Hélas, elles ne semblent pas fonctionner complètement en Ruby 1.9, parce que, par exemple :

    $ cat caller.rb
    require File.join(File.dirname(__FILE__), 'path/to/file')
    $ cat path/to/file.rb
    puts 'Some testing'
    $ ruby caller
    Some testing
    $ pwd
    /tmp
    $ ruby /tmp/caller
    Some testing
    $ ruby tmp/caller
    tmp/caller.rb:1:in 'require': no such file to load -- tmp/path/to/file (LoadError)
        from tmp/caller.rb:1:in '<main>'
  • Une construction encore plus bizarre :`

    require File.join(File.expand_path(File.dirname(__FILE__)), 'path/to/file')

    `semble fonctionner, mais c'est bizarre et pas très joli.

  • Utilisation backports gem - il est un peu lourd, il nécessite une infrastructure rubygems et inclut des tonnes d'autres solutions de contournement, alors que je veux juste require pour travailler avec des fichiers relatifs.

Il y a un question étroitement liée à StackOverflow qui donne d'autres exemples, mais ne donne pas de réponse claire - ce qui est une bonne pratique.

Existe-t-il une solution universelle, acceptée par tous, pour faire fonctionner mon application à la fois sur Ruby <1.9.2 et >=1.9.2 ?

MISE À JOUR

Clarification : Je ne veux pas seulement des réponses du type "vous pouvez faire X" - en fait, j'ai déjà mentionné la plupart des choix de la question. Je veux raison d'être , c'est-à-dire pourquoi il s'agit d'une meilleure pratique, quels sont ses avantages et ses inconvénients et pourquoi elle devrait être choisie parmi les autres.

4voto

En backports gem permet maintenant le chargement individuel des backports.

Vous pouvez alors simplement :

require 'backports/1.9.1/kernel/require_relative'
# => Now require_relative works for all versions of Ruby

Este require n'affectera pas les versions plus récentes et ne mettra pas à jour les autres méthodes intégrées.

3voto

eradman Points 172

Une autre option consiste à indiquer à l'interprète les chemins à rechercher

ruby -I /path/to/my/project caller.rb

3voto

jptros Points 61

Les solutions basées sur __FILE__ posent un problème que je n'ai pas remarqué : elles ne fonctionnent pas avec les liens symboliques. Par exemple, disons que j'ai :

~/Projects/MyProject/foo.rb
~/Projects/MyProject/lib/someinclude.rb

Le script principal, le point d'entrée, l'application est foo.rb. Ce fichier est lié à ~/script/foo qui se trouve dans mon $PATH. Cette instruction require est cassée lorsque j'exécute 'foo' :

require File.join(File.dirname(__FILE__), "lib/someinclude")

Parce que __FILE__ est ~/scripts/foo, l'instruction require ci-dessus cherche ~/scripts/foo/lib/someinclude.rb qui n'existe manifestement pas. La solution est simple. Si __FILE__ est un lien symbolique, il doit être déréférencé. Pathname#realpath nous aidera dans cette situation :

require "pathname"
require File.join(File.dirname(Pathname.new(\_\_FILE\_\_).realpath), "lib/someinclude")

2voto

Casey Watson Points 9986

Si vous construisiez une gemme, vous ne voudriez pas polluer le chemin de chargement.

Mais dans le cas d'une application autonome, il est très pratique d'ajouter le répertoire courant au chemin de chargement, comme dans les deux premiers exemples.

Mon vote va à la première option de la liste.

J'aimerais beaucoup voir des documents sur les meilleures pratiques de Ruby.

1voto

Phrogz Points 112337

Je définirais ma propre relative_require s'il n'existe pas (c'est-à-dire sous la version 1.8) et utiliser la même syntaxe partout.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X