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


465

내 질문은 " Ruby의 include와 extend의 ​​차이점은 무엇입니까? " 비슷합니다 .

루비 require와 의 차이점은 무엇입니까 include? 난 그냥해야, 내 수업에 모듈의 방법을 사용하려면 require그것을 또는 include그것?


1
무엇의 가치를 들어, 여기에 대한 커뮤니티 문서에 대한 링크 requireinclude관련도하고, Module#append_features.

답변:


543

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

대답:

include 및 require 메소드는 매우 다른 작업을 수행합니다.

require 메소드는 대부분의 다른 프로그래밍 언어에서 include 기능을 수행합니다. 다른 파일을 실행하십시오. 또한 과거에 필요한 것을 추적하며 동일한 파일을 두 번 요구하지 않습니다. 이 추가 기능없이 다른 파일을 실행하려면로드 방법을 사용할 수 있습니다.

include 메소드는 다른 모듈에서 모든 메소드를 가져 와서 현재 모듈에 포함시킵니다. 이것은 require와 마찬가지로 파일 수준과 반대되는 언어 수준입니다. include 메소드는 다른 모듈 (보통 믹스 인이라고 함)로 클래스를 "확장"하는 기본 방법입니다. 예를 들어, 클래스가 "each"메소드를 정의하는 경우 믹스 인 모듈 Enumerable을 포함하고 콜렉션으로 작동 할 수 있습니다. 포함 동사가 다른 언어에서는 매우 다르게 사용되므로 혼동 될 수 있습니다.

출처

따라서 모듈을 확장하거나 믹스 인하는 대신 모듈을 사용하려면을 사용하십시오 require.

이상하게도 Ruby require는 C와 유사 include하지만 Ruby include는 C와 거의 다릅니다 include.


45
실제로 C의 include는 필요에 따라 파일을로드하지 않지만 대신 #include 행을 파일 내용으로 바꿉니다. 포함 된 파일은 '헤더'일 필요는 없으며 #include는 파일의 시작 부분에있을 필요는 없지만 클래스 나 메서드 정의와 같이 어디에나있을 수 있습니다. 즉, 파일에 일부 메소드를 작성하여 클래스 코드에 포함시켜 C ++에서 믹스 인을 수행 할 수 있습니다. 정확히 루비에서했던 것과 같습니다. 실제로 C에서는 일반적인 관행이 아니더라도 그들은 그리 멀지 않습니다.
mb14

13
이 답변은 예제를 포함하면 도움이 될 수 있습니다.
트래비스 곰

12
mb14의 의견은 이것을 암시하지만 명시 적으로 진술합니다 : 답변의 말과 달리 require는 파일을 "실행" 하지 않고 파일을 포함하는 파일의 일부 인 것처럼로드합니다. 이것은 의미 론적 nitpicking처럼 보이지만 실제로는 중요한 차이점입니다.
Lonny Eachus

좋은 설명입니다. 마지막으로 '이상하게도 루비의 요구는 C의 포함과 유사하지만, 루비의 포함은 C의 포함과 거의 같지 않습니다.'
ArtSabintsev

1
@GregSchmit : includeRuby에서 단순히 상속입니다. class C; include M endM의 슈퍼 클래스 C와의 (구) 슈퍼 클래스 C의 슈퍼 클래스를 M. C가 include상속을 통해 작동 한다고 생각하지 않습니다 . 단순한 텍스트 / 어휘 대체라고 생각합니다.
Jörg W Mittag

100

모듈을 사용하는 경우 모든 메소드를 클래스로 가져옵니다. extend모듈 이 있는 클래스라면 모듈의 메소드를 클래스 메소드 로 "반입"한다는 의미 입니다. include모듈 이 있는 클래스라면 모듈의 메소드를 인스턴스 메소드 로 "반입"한다는 의미 입니다.

전의:

 module A
   def say
     puts "this is module A"
   end
 end

 class B
   include A
 end

 class C
   extend A
 end

B.say => B : Class에 대해 정의되지 않은 메소드 'say'

B.new.say => 이것은 모듈 A입니다

C.say => 이것은 모듈 A입니다

C.new.say => C : Class에 대해 정의되지 않은 메소드 'say'


23
나는 이것이 질문에 대답하지 않는다고 생각하지만 그것은 내가 찾던 것입니다 =)
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

2
이것은 실제로 차이점 require과 차이점에 대한 질문에 대답하지 않습니다 include.

94

메타 프로그래밍 루비 책에서

require()방법은과 비슷 load()하지만 다른 목적으로 사용됩니다. load()코드를 실행 하는 데 사용 require()하고 라이브러리를 가져 오는 데 사용 합니다.


73
답변에서 다른 언어와 비교하지 않기 위해 공감하십시오 :)
Stevo

질문의 맥락에서 답변을 제공하지 않은 것에 대한 투표는 "내 수업에있는 모듈의 메소드를 사용하고 싶은가?"
benc

57
  • 루비 require는 다른 언어 (예 : C)에서 "include"와 비슷합니다. 루비에게 다른 파일의 내용가져오고 싶다고 알려줍니다 . 다른 언어로 된 유사한 메커니즘은 다음과 같습니다.

  • Ruby includemixin에 사용되는 객체 지향 상속 메커니즘 입니다.

여기에 좋은 설명이 있습니다 .

간단한 대답은 요구와 포함이 본질적으로 관련이 없다는 것입니다.

"필수" 는 C 포함과 유사하며 초보자 혼동을 일으킬 수 있습니다. (필요한 차이점 중 하나는 필요한 파일 내부의 로컬 사용자가 필요할 때 "증발"한다는 것입니다.)

Ruby include 는 C include와 다릅니다 . include 문은 모듈을 클래스에 "혼합"합니다. 다중 상속제한된 형태입니다 . 포함 된 모듈은 문자 적으로 "is-a"관계를 포함합니다.

강조가 추가되었습니다.


7

require모듈 을 사용해 본 적이 있습니까? 결과는 어땠습니까? 단지 시도:

MyModule = Module.new
require MyModule # see what happens

모듈은 필요하지 않으며 포함되어 있습니다!


여기의 주장이 올바르지 않습니다. 모듈이 필요할 수 있습니다. 위의 코드를 실행하는 사람 TypeError은 단어 Module가로 변경 되면 동일한 결과 ( ) 를 받는다는 것을 알게 될 것입니다 Class.
pjd

7

Ruby 1.9 프로그래밍 에서

계속하기 전에 include 문에 대해 몇 가지 사항을 설명하겠습니다. 첫째, 파일과 관련이 없습니다. C 프로그래머는 컴파일 중에 한 파일의 내용을 다른 파일에 삽입하기 위해 #include라는 전처리 지시문을 사용합니다. Ruby include 문은 단순히 모듈을 참조합니다. 해당 모듈이 별도의 파일에있는 경우 include를 사용하기 전에 require (또는 덜 일반적으로 사용되는 사촌,로드)를 사용하여 해당 파일을 끌어 와야합니다. 둘째, Ruby include는 단순히 모듈의 인스턴스 메소드를 클래스에 복사하지 않습니다. 대신 클래스에서 포함 된 모듈을 참조합니다. 여러 클래스에 해당 모듈이 포함되어 있으면 모두 같은 것을 가리 킵니다. 프로그램이 실행되는 동안에도 모듈 내에서 메소드의 정의를 변경하면


3

포함 아래에 표시된대로 모듈을 클래스에 포함 시키면 마치 모듈 내에 정의 된 코드를 가져 와서 '포함'하는 클래스에 삽입 한 것과 같습니다. '믹싱'동작을 허용합니다. 예를 들어 모듈 내에 동일한 코드가 필요한 여러 클래스가있는 경우 중복을 피하기 위해 코드를 건조하는 데 사용됩니다.

로드로드 방법은 해당 라이브러리가로드되었는지 여부를 추적하지 않는다는 점을 제외하고는 require 메소드와 거의 같습니다. 따라서 라이브러리를 여러 번로드 할 수 있으며로드 방법을 사용할 때 라이브러리 파일 이름의 ".rb"확장자를 지정해야합니다.

Require require 메소드를 사용하면 라이브러리를로드하고 라이브러리가 두 번 이상로드되는 것을 방지 할 수 있습니다. require 메소드는 처음으로 동일한 라이브러리를로드하려고하면 'false'를 리턴합니다. 로드하는 라이브러리가 별도의 파일에 정의 된 경우 (필요한 경우) require 메소드 만 사용해야합니다.

http://ionrails.com/2009/09/19/ruby_require-vs-load-vs-include-vs-extend/를 선호 할 수 있습니다


3

다음은 require와 include의 기본적인 차이점입니다.

요구 사항 :

  1. Require는 파일 시스템에서 파일을 읽고, 구문 분석하고, 메모리에 저장 한 후 지정된 위치에서 파일을 실행합니다. 즉, 스크립트가 실행 중일 때 변경 사항이 반영되지 않은 경우에도 변경 사항이 적용됩니다.
  2. 모듈 이름이 아닌 이름으로 파일이 필요합니다.
  3. 일반적으로 라이브러리 및 확장에 사용됩니다.

포함:

  1. 모듈을 클래스에 포함 시키면 모듈에 정의 된 코드를 가져 와서 클래스에 삽입 한 것처럼 동작합니다.
  2. 파일 이름이 아닌 모듈 이름을 포함합니다.
  3. 일반적으로 코드를 정리하고 코드에서 중복을 제거하는 데 사용됩니다.

2
require(name)

bolean true / false를 리턴합니다.

require에 매개 변수로 전달 된 이름, ruby는로드 경로에서 해당 이름의 소스 파일을 찾으려고 시도합니다. require 메소드는 처음으로 동일한 라이브러리를로드하려고하면 'false'를 리턴합니다. 로드하는 라이브러리가 별도의 파일에 정의 된 경우 require 메소드 만 사용해야합니다. 따라서 해당 라이브러리가 이미로드되었는지 여부를 추적합니다.

include module_name

두 개의 다른 클래스에 필요한 메소드가 있다고 가정하십시오. 그런 다음 두 수업에서 모두 쓸 필요는 없습니다. 대신 할 수있는 일은 모듈에서 정의하는 것입니다. 그런 다음이 클래스를 다른 클래스에 포함 시키십시오. DRY 원칙을 보장하기 위해 Ruby에서 제공합니다. 중복을 피하기 위해 코드를 건조하는 데 사용됩니다.


2

포함

include당신이 모듈 내에 정의 된 코드를 가지고 가고 당신이 그것을 '포함'클래스 내에서 그것을 삽입 된 것처럼 클래스에 모듈, 그것은이다. '믹싱'동작을 허용합니다. 예를 들어 모듈 내에 동일한 코드가 필요한 여러 클래스가있는 경우 중복을 피하기 위해 코드를 건조하는 데 사용됩니다.

module Log 
  def class_type
    "This class is of type: #{self.class}"
  end
end

class TestClass 
  include Log 
  # ... 
end

tc = TestClass.new.class_type # -> success
tc = TestClass.class_type # -> error

필요

require 메소드를 사용하면 라이브러리를로드 할 수 있으며 라이브러리가 두 번 이상로드되지 않습니다. require 메소드는 처음으로 동일한 라이브러리를로드하려고하면 'false'를 리턴합니다. 로드하는 라이브러리가 별도의 파일에 정의 된 경우 (필요한 경우) require 메소드 만 사용해야합니다.

따라서 해당 라이브러리가 이미로드되었는지 여부를 추적합니다. 라이브러리 파일 이름의 ".rb"확장자를 지정할 필요도 없습니다. 다음은 require를 사용하는 방법의 예입니다. require 메소드를“.rb”파일 맨 위에 놓으십시오.

하중

로드 방법은 라이브러리가로드되었는지 여부를 추적하지 않는다는 점을 제외하고는 require 메소드와 거의 같습니다. 따라서 라이브러리를 여러 번로드 할 수 있으며로드 방법을 사용할 때 라이브러리 파일 이름의 ".rb"확장자를 지정해야합니다.

넓히다

include 대신 extend 메소드를 사용하는 경우 모듈 메소드를 인스턴스 메소드 대신 클래스 메소드로 추가합니다.

module Log 
  def class_type
    "This class is of type: #{self.class}"
  end
end

class TestClass 
  extend Log 
  # ... 
end

tc = TestClass.class_type

2

'로드'-파일의 내용을 삽입합니다 (파일을 호출 할 때마다 파일 구문 분석)

'필수'-파일 구문 분석 컨텐츠를 삽입합니다 (파일 구문 분석 및 메모리에 저장)

'포함'-모듈을 클래스에 포함하고 모듈 내부의 메소드를 클래스의 인스턴스 메소드로 사용할 수 있습니다.

'Extend'- 모듈을 클래스에 포함시키고 모듈 내부의 메소드를 클래스 메소드로 사용할 수 있습니다.

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