source

루비에서 include와 extend의 차이점은 무엇입니까?

factcode 2023. 6. 3. 08:46
반응형

루비에서 include와 extend의 차이점은 무엇입니까?

루비 메타프로그래밍에 대해 생각해 보는 중입니다.믹스인/모듈은 항상 저를 혼란스럽게 합니다.

  • include: 대상 클래스의 인스턴스 메서드로 지정된 모듈 메서드의 혼합
  • extend: 대상 클래스의 클래스 메서드로 지정된 모듈 메서드에서 혼합

그래서 가장차이점은 이것뿐인가요 아니면 더 큰 용이 숨어 있나요? 예를 들어.

module ReusableModule
  def module_method
    puts "Module Method: Hi there!"
  end
end

class ClassThatIncludes
  include ReusableModule
end
class ClassThatExtends
  extend ReusableModule
end

puts "Include"
ClassThatIncludes.new.module_method       # "Module Method: Hi there!"
puts "Extend"
ClassThatExtends.module_method            # "Module Method: Hi there!"

extend - 지정한 모듈의 메서드 및 상수를 대상의 메타 클래스(즉, 싱글톤 클래스)에 추가합니다.

  • Klazz.extend(Mod)이제 클라즈는 모드의 방법을 가지고 있습니다(클래스 방법으로서).
  • obj.extend(Mod)는 (, mod의 .obj.class에는 이러한 메서드가 추가되어 있습니다.
  • extend인 방법입니다.

include - 기본적으로 대상 모듈/클래스의 인스턴스 메서드로 지정된 모듈의 메서드에 혼합됩니다.

  • class Klazz; include Mod; end;이제 클라즈의 모든 인스턴스는 모드의 방법(인스턴스 방법)에 액세스할 수 있습니다.
  • include는 컨테이너 클래스/컨테이너 내에서 호출되도록 의도되었기 때문에 비공개 메서드입니다.

그러나 모듈은 매우 자주 오버라이드합니다. include원숭이를 이용한 행동.included방법.이것은 레거시 레일즈 코드에서 매우 두드러집니다. 자세한 내용은 예후다 카츠가 제공합니다.

에 대한 정보include동작입니다.

class Klazz
  include Mod
end
  • 모드가 이미 Klazz 또는 그 조상 중 하나에 포함되어 있는 경우, 포함 문은 영향을 주지 않습니다.
  • 그것들이 충돌하지 않는 한, 그것은 또한 클라즈에 있는 모드의 상수를 포함합니다.
  • 에게 Mod의 변수: Clazz는 모드변접수있수근습다니할에듈의모,있▁it다습)에 대한 액세스를 제공합니다.@@foo또는@@bar
  • 순환 포함이 있는 경우 ArgumentError를 발생시킵니다.
  • 모듈을 호출자의 직계 조상(예: 하지만 모드는 클라즈의 사슬에 추가되지 않았습니다. 슈퍼 클래스 슈퍼 클래스초특급의그래서, 전화하기superKlazz#foo에서는 Mod#foo를 확인한 후 Klazz의 실제 슈퍼 클래스의 foo 메서드를 확인합니다.자세한 내용은 RubySpec을 참조하십시오.)

물론 루비 코어 문서는 항상 이러한 작업을 수행하기에 가장 적합합니다.RubySpec 프로젝트는 기능을 정확하게 문서화했기 때문에 환상적인 리소스이기도 했습니다.

당신이 한 말이 맞습니다.하지만, 그것보다 더 많은 것이 있습니다.

Klazz 모듈 및Mod를 포함하여, 을 포함하여ModKlazz에는 의예들설니다명의 있습니다.Klazz에 합니다.Mod의 방법.또는 확장할 수 있습니다.Klazz와 함께Mod수업하기 Klazz에 합니다.Mod의 방법.그러나 다음을 사용하여 임의 개체를 확장할 수도 있습니다.o.extend Mod이 경우 개별 객체는 다음과 같이 됩니다.Mod의 가 동일한 o하지마.

맞습니다.

include는 실제로 (문서에서) append_features의 별칭입니다.

Ruby의 기본 구현은 이 모듈이 모듈 또는 그 상위 모듈 중 하나에 아직 추가되지 않은 경우 이 모듈의 상수, 메서드 및 모듈 변수를 모듈에 추가하는 것입니다.

모듈을 클래스로 구성하면 모듈 메서드를 인스턴스 메서드로 가져옵니다.

그러나 모듈을 클래스로 구성하면 모듈 메서드를 클래스 메서드로 가져옵니다.

들어 에는 모듈을 예로 들 수 .Module_test다음과 같이 정의됩니다.

module Module_test
  def func
    puts "M - in module"
  end
end

자, 모듈입니다.클래스를 정의하면A다음과 같이:

class A
  include Module_test
end

a = A.new
a.func

은 다음과 같습니다.M - in module.

만약 우리가 라인을 교체한다면,include Module_test와 함께extend Module_test다시 합니다.undefined method 'func' for #<A:instance_num> (NoMethodError).

호출 변경하기a.funcA.func이 다음과 같이됩니다.M - in module.

위의 코드 실행으로부터, 우리가 모듈을 구성할 때, 그것의 메소드는 인스턴스 메소드가 되고, 우리가 모듈을 구성할 때, 그것의 메소드는 클래스 메소드가 되는 것이 분명합니다.

RubySpec을 탐색하는 팁을 포함하여 다른 모든 답변은 좋습니다.

https://github.com/rubyspec/rubyspec/blob/master/core/module/include_spec.rb

https://github.com/rubyspec/rubyspec/blob/master/core/module/extend_object_spec.rb

사용 사례:

클래스에 모듈 재사용 가능 모듈을 포함하는 경우여기에는 메서드, 상수, 클래스, 하위 모듈 및 기타 선언이 참조됩니다.

클래스를 확장하는 경우모듈 재사용 가능 모듈로 확장하면 메서드와 상수가 복사됩니다.분명히, 주의하지 않으면 정의를 동적으로 복제하여 많은 메모리를 낭비할 수 있습니다.

ActiveSupport를 사용하는 경우:문제입니다. .included() 기능을 사용하면 포함 클래스를 직접 다시 작성할 수 있습니다. 문제 내부의 모듈 클래스 메서드가 포함 클래스로 확장(복사)됩니다.

작동하는 메커니즘에 대해서도 설명하고 싶습니다.제가 틀렸다면 수정해주세요.

사용할 때include우리는 몇 가지 방법을 포함하는 모듈에 우리 반의 링크를 추가하고 있습니다.

class A
include MyMOd
end

a = A.new
a.some_method

객체에는 메서드가 없고 클래스와 모듈만 있습니다.그래서 언제a메시지 수신some_method검색 방법을 시작합니다.some_methoda의 고유 클래스, 그렇다면A클래스 그리고 그 다음에A클래스 모듈(역순으로, 마지막으로 포함된 승리)이 있는 경우.

사용할 때extend우리는 객체의 고유 클래스에 있는 모듈에 링크를 추가하고 있습니다.따라서 A.new.extend(MyMod)를 사용하면 모듈에 링크를 A의 인스턴스 고유 클래스 또는a' A하면 A) 에 링크를 입니다. 그리고 A.extend(MyMod)를 사용하면 A(객체의, 클래스도 객체임) 고유 클래스에 링크를 추가합니다.A'.

method for 법방경:a다음과 : a=> => 을 a' => vmdk에 연결했습니다. a => a' => a' => A' 모듈입니다.

또한 조회 경로를 변경하는 추가 방법이 있습니다.

a => a' => A에 추가된 모듈 => A => A에 포함된 모듈

제가 영어를 잘 못해서 죄송합니다.

저는 매우 유용한 기사를 발견했습니다.include,extend그리고.prepend클래스 내에서 사용되는 메서드:

include, 모듈 메소드는 클래스에 추가합니다.extend모듈 메서드를 클래스 메서드로 추가합니다.에 따라 .

언급URL : https://stackoverflow.com/questions/156362/what-is-the-difference-between-include-and-extend-in-ruby

반응형