Perché Ruby 1.9.2 rimuove “.” Da LOAD_PATH e qual è l’alternativa?

Gli ultimi changeset di Ruby 1.9.2 non rendono più la directory corrente . parte del tuo LOAD_PATH . Ho un numero non banale di Rakefiles che lo presuppongono . fa parte del LOAD_PATH , quindi questo li ha rotti (hanno riportato “nessun file di questo tipo da caricare” per tutte le istruzioni necessarie che si basano sul percorso del progetto). C’era una giustificazione particolare per fare questo?

Per quanto riguarda una correzione, aggiungendo $: << "." funziona ovunque, ma sembra incredibilmente hacky e non voglio farlo. Qual è il modo migliore per rendere compatibile Rakefiles 1.9.2+?

Era considerato un rischio “di sicurezza”.

Puoi aggirare usando percorsi assoluti

 File.expand_path(__FILE__) et al 

o facendo

 require './filename' (ironically). 

o usando

 require_relative 'filename' 

o aggiungendo una directory “include”

 ruby -I . ... 

o lo stesso, usando irb;

 $irb -I . 

Ci sono due ragioni:

  • robustezza e
  • sicurezza

Entrambi si basano sullo stesso principio di base: in generale, non è ansible sapere quale sia la directory corrente, quando viene eseguito il codice. Ciò significa che, quando si richiede un file e si dipende dal fatto che si trovi nella directory corrente, non si ha modo di controllare se quel file sarà presente o se si tratta del file che ci si aspetta effettivamente di essere lì.

Come altre risposte sottolineano, è un rischio per la sicurezza perché . nel percorso di caricamento si riferisce alla directory di lavoro attuale Dir.pwd , non alla directory del file corrente che viene caricato. Quindi chiunque stia eseguendo il tuo script può cambiarlo semplicemente inserendo un cd in un’altra directory. Non bene!

Ho usato percorsi completi costruiti da __FILE__ come alternativa.

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

A differenza di require_relative , questo è retrocompatibile con Ruby 1.8.7.

Utilizza require_relative 'file_to_require'

Getta questo nel tuo codice per rendere require_relative work in 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 

” nel tuo percorso è stata a lungo considerata una brutta cosa nel mondo Unix (vedi, ad esempio, http://www.faqs.org/faqs/unix-faq/faq/part2/section-13.html ). Presumo che i Ruby siano stati persuasi della saggezza di non farlo.

Ho trovato questo cambiamento confondente fino a quando ho realizzato un paio di cose.

Puoi impostare RUBYLIB nel tuo .profile (Unix) e andare avanti con la vita come hai fatto prima:

export RUBYLIB="."

Ma come accennato in precedenza, è stato a lungo considerato pericoloso farlo.

Per la maggior parte dei casi è ansible evitare problemi semplicemente chiamando i propri script Ruby con un “.” ad es ./scripts/server.

Come ha fatto notare Jörg W Mittag, penso che ciò che si desidera utilizzare sia require_relative modo che il file richiesto sia relativo al file sorgente della dichiarazione require e non alla directory di lavoro corrente.

Le tue dipendenze dovrebbero essere relative al tuo file di rake build.