Ruby에서 require_relative와 require의 차이점은 무엇입니까?


302

루비 require_relative와 의 차이점은 무엇입니까 require?


9
1.9.2 이전에는 스크립트의 현재 디렉토리가에 있었기 때문에 require_relative가 필요하지 않았습니다 $:.
Nakilon

1
require_relative는 파일을 호출하는 파일과 관련하여 특별히 지정된 파일이 필요합니다. $ LOAD_PATH에 포함 된 파일이 필요합니다.
Donato

=> 차이점에 대한 유용한 기사 medium.com/@ellishim/...
아메드 hamdy

답변:


298

문서를 살펴보십시오 .

require_relative명령문을 require포함하는 파일과 관련된 파일을로드 할 수 있도록 하여 내장 메소드 를 보완합니다 require_relative.

예를 들어, "test"디렉토리에 단위 테스트 클래스가 있고 테스트 "test / data"디렉토리 아래에 해당 클래스에 대한 데이터가있는 경우 테스트 케이스에서 다음과 같은 행을 사용할 수 있습니다.

require_relative "data/customer_data_1"

28
require './file.rb'와 사이에 차이가 require_relative 'file.rb'있습니까?
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

69
@CiroSantilli 예. require_relative" 문을 포함하는 파일과 관련된require_relative 파일을로드"할 수 있습니다 . 으로 require, ./현재 작업 디렉토리에 상대적인 경로를 나타냅니다.
Ajedi32

16
require str항상 $ LOAD_PATH의 디렉토리를 검색 한다는 점에 유의하는 것이 더 중요하다고 생각합니다 . require_relative로드해야하는 파일이로드를 요구하는 파일과 관련되어있을 때 사용해야합니다 . require"외부"종속성을 위해 예약하십시오 .
rthbound

97

require_relative 편리한 하위 집합입니다 require

require_relative('path')

같음 :

require(File.expand_path('path', File.dirname(__FILE__)))

만약 __FILE__ 가 정의되어 있거나 LoadError그렇지 않으면 발생합니다.

이것은 다음을 의미합니다.

  • require_relative 'a'그리고 require_relative './a'받는 상대 필요로 현재 파일 (__FILE__ ).

    결과는 호출자의 현재 디렉토리에 의존하지 않기 때문에 라이브러리 내부에서 필요할 때 사용하려는 것입니다.

  • eval('require_relative("a.rb")')제기 LoadError하기 때문에 __FILE__내부에 정의되어 있지 않습니다eval .

    이것이 바로 require_relativeRSpec 테스트에서 사용할 수없는 이유 eval입니다.

다음 작업 만 가능합니다 require:

  • require './a.rb'현재 디렉토리에 상대적인 요구

  • require 'a.rb'검색 경로 ( $LOAD_PATH)를 사용하여 필요합니다. 현재 디렉토리 또는 경로와 관련된 파일을 찾지 않습니다.

    require_relative문서에서 "파일 이름이 절대 경로로 해석되지 않는 경우"(예 : /또는 ./또는로 시작 ../하는 경우) 에만 경로 검색이 발생한다고 문서에서 말하고 있기 때문에 불가능 합니다 File.expand_path.

다음 작업은 둘 다 가능하지만 require짧고 효율적이므로 사용하고 싶을 것입니다.

  • require '/a.rb'require_relative '/a.rb'모두 절대 경로를 필요로한다.

소스 읽기

문서가 명확하지 않은 경우 소스를 살펴 보는 것이 좋습니다 (문서의 소스를 전환). 어떤 경우에는 무슨 일이 일어나고 있는지 이해하는 데 도움이됩니다.

필요합니다 :

VALUE rb_f_require(VALUE obj, VALUE fname) {
  return rb_require_safe(fname, rb_safe_level());
}

require_relative :

VALUE rb_f_require_relative(VALUE obj, VALUE fname) {
    VALUE base = rb_current_realfilepath();
    if (NIL_P(base)) {
        rb_loaderror("cannot infer basepath");
    }
    base = rb_file_dirname(base);
    return rb_require_safe(rb_file_absolute_path(fname, base), rb_safe_level());
}

이를 통해 우리는 결론을 내릴 수 있습니다.

require_relative('path')

와 같다:

require(File.expand_path('path', File.dirname(__FILE__)))

때문에:

rb_file_absolute_path   =~ File.expand_path
rb_file_dirname1        =~ File.dirname
rb_current_realfilepath =~ __FILE__

74

Ruby API에서 :

require_relative는 require_relative 문이 포함 된 파일과 관련된 파일을로드 할 수 있도록함으로써 내장 메소드 요구 사항을 보완합니다.

require를 사용하여 파일을로드하면 일반적으로 시스템에서 올바르게 설치되어 액세스 가능한 기능에 액세스하는 것입니다. require는 프로젝트 코드 내에서 파일을로드하기위한 좋은 솔루션을 제공하지 않습니다. 이는 개발 단계에서 테스트 데이터에 액세스하거나 외부에서 사용하지 않고 프로젝트 내부에서 "잠긴"파일에 액세스하는 데 유용 할 수 있습니다.

예를 들어, "test"디렉토리에 단위 테스트 클래스가 있고 테스트 "test / data"디렉토리 아래에 해당 클래스에 대한 데이터가있는 경우 테스트 케이스에서 다음과 같은 행을 사용할 수 있습니다.

require_relative "data/customer_data_1" 

"test"나 "test / data"는 루비의 라이브러리 경로에 있지 않을 것이기 때문에 (그리고 정당한 이유로) 정상적인 요구에서는 찾지 못할 것입니다. require_relative는이 특정 문제에 대한 좋은 솔루션입니다.

로드중인 파일의 확장자 (.rb 또는 .so)를 포함하거나 생략 할 수 있습니다.

경로는 to_str에 응답해야합니다.

http://extensions.rubyforge.org/rdoc/classes/Kernel.html 에서 설명서를 찾을 수 있습니다 .


50

요약

사용하여 require설치 보석에 대한

를 사용하여 require_relative로컬 파일에 대한

require를 사용하여 $LOAD_PATH파일을 찾습니다.
require_relative명령문을 사용하여 파일의 현재 위치를 사용합니다.


요구하다

요구 사항은 gem install [package]해당 기능을 위해 시스템 어딘가에 패키지 를 설치 (예 :)해야합니다.

사용하는 경우 require당신은 할 수 있습니다 "사용 ./현재 디렉토리, 예를 들어, 한 파일에 대해"형식을 require "./my_file"하지만 일반적인 또는 권장 방법이 아닙니다 당신은 사용해야합니다 require_relative대신.

require_relative

이것은 단순히 'require_relative 문으로 파일의 위치에 상대적인'파일을 포함한다는 것을 의미합니다. 나는 일반적 예는, "최대"반대로 그 파일이 현재 디렉토리 트리 "에서"해야한다 추천 하지 않습니다 사용

require_relative '../../../filename'

불필요하고 취약한 종속성을 생성하는 경향이 있기 때문에 파일 시스템 내에서 (최대 3 개의 디렉토리 레벨). 그러나 어떤 경우에는 디렉토리 트리 내에서 이미 '심층'인 경우 다른 디렉토리 트리 분기가 "위로"아래로 필요할 수 있습니다. 더 간단하게 는이 저장소 외부의 파일에 require_relative를 사용하지 마십시오 (2018 년 말 현재이 시점에서 사실상 표준 인 git을 사용한다고 가정).

require_relative 문과 함께 파일require_relative 의 현재 디렉토리 를 사용하십시오 (따라서 명령을 사용하는 현재 디렉토리 일 필요는 없습니다). 이렇게하면 경로는 항상 같은 방식으로 필요한 파일에 상대적이므로 "안정된"경로를 유지합니다 .require_relative


27

정답은 정확하지만 매우 기술적입니다. 루비를 처음 접하는 사람들에게 :

  • require_relative 작성한 다른 파일에서 코드를 가져 오는 데 사용됩니다.

예를 들어 데이터가 ~/my-project/data.rb있고 데이터 를 포함하려면 ~/my-project/solution.rb어떻게해야합니까? 에 solution.rb당신을 추가합니다 require_relative 'data'.

이러한 파일이 동일한 디렉토리에있을 필요는 없습니다. require_relative '../../folder1/folder2/data'유효합니다.

  • require 다른 사람이 작성한 라이브러리에서 코드를 가져 오는 데 가장 많이 사용됩니다.

예를 들어 active_support라이브러리에 제공된 도우미 함수 중 하나를 사용하려면 어떻게해야 합니까? gem을 gem install activesupport파일 에 설치 한 다음 파일 에 설치해야 합니다 require 'active_support'.

require 'active_support/all'
"FooBar".underscore

다르게 말했다-

  • require_relative 파일을 호출하는 파일과 관련하여 특별히 지정된 파일이 필요합니다.

  • require에 포함 된 파일이 필요합니다 $LOAD_PATH.


3
이 답변에 어떻게 투표하고 맨 위로 올릴 수 있습니까? 그러면이 질문 페이지의 모든 방문자가 두뇌를 깨지 않고 바로 명확하고 이해하기 쉬운 답변을 얻을 수 있습니까?
TiredOfProgramming

16

방금 RSpec의 코드 require_relative에 O (1) 상수 및 requireO (N) 선형 에 대한 의견 이 있습니다. 아마도 차이점은 require_relative보다 선호하는 것 require입니다.


1
흥미 롭군 나는 속도 비교에 대한 정보를 찾고 여기에 착륙했습니다. require_relative로더가 파일을 찾기 위해로드 경로를 통과 할 필요가 없기 때문에 더 빠르다고 생각했습니다 . 기본적 require_relative으로 직접 링크를 제공합니다.
클린트 Pachl

require_relative 속도 및 RSpec 변경 로그 에 대한 초기 토론 .
클린트 Pachl

1

Windows를 사용할 require './1.rb'때 스크립트가 로컬 또는 매핑 된 네트워크 드라이브에서 실행되는 경우 사용할 수 있지만 UNC \\servername\sharename\folder경로 에서 실행 하는 경우 사용할 수 있다고 덧붙이고 싶습니다 require_relative './1.rb'.

나는 다른 이유로 사용할 토론에 참여하지 않습니다.


require_relative파일을 어떻게로드하는지 알고 싶었 습니다. 이것에 대해 아이디어를 던져 주시겠습니까? stackoverflow.com/questions/43487784/…
시겠습니까?
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.