Pourquoi Ruby 1.9.2 supprime-t-il “.” De LOAD_PATH, et quelle est l’alternative?

Les dernières modifications apscopes à Ruby 1.9.2 ne font plus le répertoire actuel . partie de votre LOAD_PATH . J’ai un nombre non négligeable de fichiers Rakefile qui supposent cela . fait partie de LOAD_PATH , donc cela les a cassés (ils ont signalé “aucun fichier de ce type à charger” pour toutes les instructions LOAD_PATH basées sur le chemin du projet). Y at-il une justification particulière à cela?

Comme pour un correctif, en ajoutant $: << "." partout fonctionne, mais semble incroyablement pirate et je ne veux pas faire ça. Quelle est la manière préférée de rendre mon Rakefiles 1.9.2+ compatible?

    C’était considéré comme un risque de “sécurité”.

    Vous pouvez le contourner en utilisant des chemins absolus

     File.expand_path(__FILE__) et al 

    ou faire

     require './filename' (ironically). 

    ou en utilisant

     require_relative 'filename' 

    ou en ajoutant un répertoire “include”

     ruby -I . ... 

    ou même, en utilisant irb;

     $irb -I . 

    Il y a deux raisons:

    • robustesse et
    • Sécurité

    Les deux sont basés sur le même principe sous-jacent: en général, vous ne pouvez simplement pas savoir quel est le répertoire actuel, lorsque votre code est exécuté. Ce qui signifie que lorsque vous avez besoin d’un fichier et que cela dépend de son emplacement dans le répertoire en cours, vous n’avez aucun moyen de contrôler si ce fichier sera présent, ou si c’est le fichier auquel vous vous attendez réellement.

    Comme d’autres réponses le font remarquer, c’est un risque de sécurité parce que . dans votre chemin de chargement se réfère au répertoire de travail actuel Dir.pwd , pas au répertoire du fichier en cours de chargement. Ainsi, quiconque exécute votre script peut changer cela simplement en cd dans un autre répertoire. Pas bon!

    J’ai utilisé des chemins complets construits à partir de __FILE__ comme alternative.

     require File.expand_path(File.join(File.dirname(__FILE__), 'filename')) 

    Contrairement à require_relative , ceci est rétrocompatible avec Ruby 1.8.7.

    Utilisez require_relative 'file_to_require'

    Jetez ceci dans votre code pour faire fonctionner require_relative en 1.8.7:

     unless Kernel.respond_to?(:require_relative) module Kernel def require_relative(path) require File.join(File.dirname(caller.first), path.to_str) end end end 

    ‘.’ dans votre chemin a longtemps été considéré comme une mauvaise chose dans le monde Unix (voir, par exemple, http://www.faqs.org/faqs/unix-faq/faq/part2/section-13.html ). Je suppose que les gens de Ruby ont été persuadés de la sagesse de ne pas le faire.

    J’ai trouvé que c’était un changement confus jusqu’à ce que je réalise quelques choses.

    Vous pouvez définir RUBYLIB dans votre fichier .profile (Unix) et continuer votre vie comme vous l’avez fait auparavant:

    export RUBYLIB="."

    Mais comme mentionné ci-dessus, cela a longtemps été considéré comme dangereux.

    Pour la grande majorité des cas, vous pouvez éviter les problèmes en appelant simplement vos scripts Ruby avec un “.” par exemple ./scripts/server.

    Comme Jörg W Mittag l’a souligné, je pense que ce que vous voulez utiliser est require_relative donc le fichier que vous souhaitez est relatif au fichier source de la déclaration de require et non au répertoire de travail actuel.

    Vos dépendances doivent être relatives à votre fichier de génération de rake.