web-dev-qa-db-de.com

Warum entfernt Ruby 1.9.2 "." Aus LOAD_PATH und was ist die Alternative?

Die letzten Änderungen an Ruby 1.9.2 führen nicht mehr zum aktuellen Verzeichnis . Teil Ihres LOAD_PATH. Ich habe eine nicht triviale Anzahl von Rakefiles, die davon ausgehen, dass . ist Teil von LOAD_PATH, so dass dies sie brach (sie meldeten "keine solche Datei zu laden" für alle erfordern Anweisungen, die aus dem Projektpfad basieren). Gab es dafür eine besondere Rechtfertigung?

Wie für einen Fix, Hinzufügen von $: << "." überall funktioniert, scheint aber unglaublich hacky und ich will das nicht tun. Was ist der bevorzugte Weg, um meine Rakefiles 1.9.2+ kompatibel zu machen?

154
John Feminella

Es wurde als "Sicherheitsrisiko" eingestuft.

Sie können es umgehen, indem Sie absolute Pfade verwenden

File.expand_path(__FILE__) et al

oder zu tun

require './filename' (ironically).

oder mit

require_relative 'filename'

oder Hinzufügen eines "include" -Verzeichnisses

Ruby -I . ...

oder dasselbe mit irb;

$irb -I .
140
rogerdpack

Es gibt zwei Gründe:

  • robustheit und
  • sicherheit

Beide basieren auf dem gleichen Grundprinzip: Im Allgemeinen können Sie bei der Ausführung Ihres Codes einfach nicht wissen, wie das aktuelle Verzeichnis lautet. Das bedeutet, dass Sie, wenn Sie eine Datei benötigen und davon abhängen, dass sie sich im aktuellen Verzeichnis befindet, nicht steuern können, ob diese Datei überhaupt vorhanden ist oder ob es sich um die Datei handelt, von der Sie tatsächlich erwarten, dass sie vorhanden ist.

34
Jörg W Mittag

Wie in anderen Antworten darauf hingewiesen wird, ist dies ein Sicherheitsrisiko, da . in Ihrem Ladepfad bezieht sich auf das aktuelle Arbeitsverzeichnis Dir.pwd, nicht das Verzeichnis der aktuell geladenen Datei. Wer also Ihr Skript ausführt, kann dies einfach durch cd in ein anderes Verzeichnis ändern. Nicht gut!

Ich habe vollständige Pfade verwendet, die aus __FILE__ als Alternative.

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

Nicht wie require_relative, dies ist abwärtskompatibel mit Ruby 1.8.7.

16
Jonathan Tran

Verwenden require_relative 'file_to_require'

Fügen Sie dies in Ihren Code ein, damit require_relative in 1.8.7 funktioniert:

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
8
Tyler Brock

'.' auf Ihrem Weg wurde lange als eine schlechte Sache in der Unix-Welt angesehen (siehe zum Beispiel http://www.faqs.org/faqs/unix-faq/faq/part2/section-13.html ). Ich nehme an, die Ruby Leute sind von der Weisheit überzeugt worden, das nicht zu tun.

6
Rodger

Ich fand das eine verwirrende Veränderung, bis mir ein paar Dinge klar wurden.

Sie können RUBYLIB in Ihrem .profile (Unix) einstellen und so weitermachen wie bisher:

export RUBYLIB="."

Aber wie oben erwähnt, wurde dies lange als unsicher eingestuft.

In den allermeisten Fällen können Sie Probleme vermeiden, indem Sie Ihre Ruby Scripts mit einem vorangestellten '.', Z. B. ./scripts/server, aufrufen.

3
Dylan

Wie Jörg W Mittag betonte, ist das, was Sie verwenden möchten, require_relative. Die Datei, die Sie benötigen, ist also relativ zur Quelldatei der require -Deklaration und nicht zum aktuellen Arbeitsverzeichnis.

Ihre Abhängigkeiten sollten relativ zu Ihrer Rake-Build-Datei sein.

3
Martin