File.expand_path (“../../ Gemfile”, __FILE__) 어떻게 작동합니까? 파일은 어디에 있습니까?


84

ENV["BUNDLE_GEMFILE"] = File.expand_path("../../Gemfile", __FILE__)

일부 디렉토리에서 .rb 파일에 액세스하려고하는데 튜토리얼에서이 코드를 사용하라고 지시하지만 gem 파일을 찾는 방법을 알 수 없습니다.


1
또한 질문을 참조 stackoverflow.com/questions/4333286
테오

답변:


194
File.expand_path('../../Gemfile', __FILE__)

현재 파일과 관련된 경로를 알고있을 때 파일의 절대 경로를 가져 오는 다소 못생긴 Ruby 관용구입니다. 작성하는 또 다른 방법은 다음과 같습니다.

File.expand_path('../Gemfile', File.dirname(__FILE__))

둘 다 추악하지만 첫 번째 변형은 더 짧습니다. 그러나 첫 번째 변형은 익숙해지기 전까지는 매우 직관적이지 않습니다. 왜 추가 ..? (그러나 두 번째 변형은 왜 필요한지에 대한 단서를 줄 수 있습니다).

작동 방식 : File.expand_path두 번째 인수 (기본값은 현재 작업 디렉터리)에 상대적인 첫 번째 인수의 절대 경로를 반환합니다. __FILE__코드가있는 파일의 경로입니다.이 경우 두 번째 인수는 파일의 경로이고 File.expand_path디렉토리를 가정 ..하므로 경로를 올바르게 가져 오려면 추가 경로를 추가 해야합니다. 작동 방식 :

File.expand_path기본적으로 다음과 같이 구현됩니다 (다음 코드 path에서 값은 ../../Gemfile이고 relative_to값은 /path/to/file.rb).

def File.expand_path(path, relative_to=Dir.getwd)
  # first the two arguments are concatenated, with the second argument first
  absolute_path = File.join(relative_to, path)
  while absolute_path.include?('..')
    # remove the first occurrence of /<something>/..
    absolute_path = absolute_path.sub(%r{/[^/]+/\.\.}, '')
  end
  absolute_path
end

(조금 더 있고, ~홈 디렉토리로 확장 되는 등 위의 코드에 다른 문제가있을 수 있습니다.)

위 코드에 대한 호출을 단계별로 수행 absolute_path하면 먼저 값을 얻은 /path/to/file.rb/../../Gemfile다음 루프의 각 라운드에 대해 첫 번째 항목 ..이 이전 경로 구성 요소와 함께 제거됩니다. 먼저 /file.rb/..제거되고 다음 라운드 /to/..에서 제거되고 /path/Gemfile.

긴 이야기를 짧게 만들려면 File.expand_path('../../Gemfile', __FILE__)현재 파일과 관련된 경로를 알고있을 때 파일의 절대 경로를 가져 오는 트릭입니다. ..상대 경로 의 추가 기능 은에서 파일 이름을 제거하는 것입니다 __FILE__.

루비 2.0에서이 Kernel호출 된 함수 __dir__로 구현됩니다 File.dirname(File.realpath(__FILE__)).


2
루비 1.9.2 이전 버전과의 비 호환성 외에 'require_relative'를 사용하면 안되는 이유가 있나요?
Danny Andrews

9
Ruby 2.0부터 사용할 수 있습니다File.expand_path('../Gemfile',__dir__)
Phrogz

Theo의이 줄은 File.expand_path assumes a directory비록 __FILE__디렉토리가 아니지만 마침내 나를 위해 클릭하도록했습니다 . 이해하기 위해 __dir__실제로 디렉토리를 사용하십시오.
mbigras

9

두 가지 참조 :

  1. File :: expand_path 메소드 문서
  2. __FILE__Ruby에서 작동 하는 방법

나는 오늘 이것을 우연히 발견했습니다.

Rails Github의 boot.rb 커밋

디렉토리 트리의 boot.rb에서 두 디렉토리 위로 이동하는 경우 :

/ railties / lib / rails / generators / rails / app / templates

Gemfile을 보면 File.expand_path("../../Gemfile", __FILE__)다음 파일 을 참조 한다고 믿게 됩니다./path/to/this/file/../../Gemfile


게시물 주셔서 감사합니다.하지만 이것은 gembundler 튜토리얼에서 나왔기 때문에 정확히 어떻게했는지 이해하려고했습니다. :)
thenengah
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.