Ruby 1.9.2가“.”을 제거하는 이유 LOAD_PATH에서 대안이 무엇입니까?


154

루비 1.9.2에 대한 최신 변경 집합은 더 이상 현재 디렉토리하지 않습니다 .당신의 일부를 LOAD_PATH. 나는 그 .중 일부 라고 가정하는 사소한 수의 Rakefile을 가지고 LOAD_PATH있기 때문에 그것들이 파산되었습니다 (프로젝트 경로를 기반으로하는 모든 요구 사항 진술에 대해 "로드 할 파일이 없습니다"). 이를위한 특별한 이유가 있습니까?

수정에 관해서는 $: << "."모든 곳 에서 추가하는 것이 효과적이지만 믿을 수 없을 정도로 해키처럼 보이고 싶지 않습니다. 내 Rakefiles 1.9.2 이상을 호환시키는 가장 좋은 방법은 무엇입니까?

답변:


141

"보안"위험으로 간주되었습니다.

절대 경로를 사용하여 해결할 수 있습니다.

File.expand_path(__FILE__) et al

또는

require './filename' (ironically).

또는 사용하여

require_relative 'filename'

또는 "include"디렉토리 추가

ruby -I . ...

또는 irb를 사용하여 동일하거나;

$irb -I .

27
을 사용하여 감았습니다 require_relative. 감사.
존 페미 넬라

11
이것은 실행 파일을 실행하기위한 경로에 현재 디렉토리를 포함하지 않는 대부분의 유닉스와 비슷합니까?
Andrew Grimm

5
require './filename'작업 디렉토리가 스크립트가있는 동일한 디렉토리로 설정된 상태에서 스크립트가 실행 된 경우에만 작동합니다. 다중 디렉토리 프로젝트에서는 그렇지 않습니다.
mxcl

34

두 가지 이유가 있습니다.

  • 견고성
  • 보안

둘 다 동일한 기본 원칙을 기반으로합니다. 일반적으로 코드가 실행될 때 현재 디렉토리가 무엇인지 알 수 없습니다. 즉, 파일이 필요할 때 현재 디렉토리에있는 파일에 의존 할 경우 해당 파일이 있을지 여부 또는 실제로있을 것으로 예상되는 파일인지 여부를 제어 할 방법이 없습니다.


5
두 파일이 서로에 대해 동일한 위치에 있어야한다는 것은 필연적으로 나쁜 요구 사항이라고 생각하지 않습니다. 그것이 사실이라면 우리는 디렉토리를 사용하지 않을 것입니다.
John Feminella

4
@ 존 페미 넬라 (John Feminella) : 파일을 서로 상대 경로에 배치하는 것과 관련이 있습니까? 문제는 .현재 작업 디렉토리와 관련하여 배치하는 것 입니다. 사용자 cd가 다른 디렉토리에있는 경우 현재 작업 디렉토리가 변경되고 스크립트를 호출 할 때 사용자가 있었던 디렉토리에 따라 파일이 require 완전히 달라집니다. 나는 그것이 좋은 생각이라고 생각하지 않습니다.
Jörg W Mittag 12

적절한 인터페이스를 유지하려면 이렇게해야합니까? $: << File.dirname(__FILE__)
Joshua Cheek

4
@Joshua Cheek : 개인적으로, 나는 그것을 좋아하지 않습니다. (그러나 그런 종류의 것들로 흩어져 있기 때문에 이전 코드를 보지 마십시오 :-)). 나는 단순히 것을 lib디렉토리가에 $LOAD_PATH다음 require을 기준으로 모든 파일 lib. 다시 말해, $LOAD_PATH올바르게 설정하는 방법을 알아 내기 위해 관리자에게 맡깁니다 . 당신이 젬을 사용하는 경우 젬이 자동으로 않기 때문에, 즉, 사소한 에 대한 당신 데비안 패키지를 사용하는 경우, 그것은 패키지 관리자의 일이다. 대체로, 그것은 꽤 잘 작동하는 것 같습니다.
Jörg W Mittag

8
@Joshua 칙 : 또한, 균형추 정렬 등의 제거에 .에서 $LOAD_PATH루비 1.9.2 도입 require_relative되는 놀라운 ... ... require현재 실행 파일의 위치를 SA 파일에 대하여 (즉, 상대적으로 File.dirname(__FILE__)).
Jörg W Mittag

16

다른 답변에서 지적했듯이 .로드 경로 Dir.pwd에서로드중인 현재 파일의 디렉토리가 아닌 현재 작업 디렉토리를 참조하기 때문에 보안 위험 이 있습니다 . 따라서 스크립트를 실행하는 사람은 단순히 cd다른 디렉토리로 이동하여 이를 변경할 수 있습니다 . 안좋다!

__FILE__대안으로 구성된 전체 경로를 사용 하고 있습니다.

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

와 달리 require_relativeRuby 1.8.7과 호환됩니다.


4
이 변형도 있습니다 (개인적으로 더 읽기 쉽습니다) : require Pathname.new(__FILE__).dirname + 'filename'
Tyler Rick

8

사용하다 require_relative 'file_to_require'

1.8.7에서 require_relative가 작동하도록하려면 코드에서 이것을 던져라 :

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


3

몇 가지 사실을 깨닫기 전까지는 이것이 혼란스러운 변화라는 것을 알았습니다.

.profile (Unix)에서 RUBYLIB를 설정하고 이전과 마찬가지로 계속 사용할 수 있습니다.

export RUBYLIB="."

그러나 위에서 언급했듯이 오랫동안 그렇게하는 것은 안전하지 않은 것으로 간주되었습니다.

대부분의 경우, 앞에 '.'를 붙여 루비 스크립트를 호출하면 문제를 피할 수 있습니다. 예 : ./scripts/server


3

Jörg W Mittag가 지적했듯이, 사용하려는 것은 현재 작업 디렉토리가 아닌 선언 require_relative의 소스 파일과 관련 이 있기 때문에 필요한 파일 이라고 생각합니다 require.

종속성은 레이크 빌드 파일과 관련이 있어야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.