Computer >> 컴퓨터 >  >> 프로그램 작성 >> Ruby

Ruby에서 `self` 이해하기

오늘은 self에 대해 이야기해보려고 합니다. . Ruby를 한동안 프로그래밍했다면 self라는 개념을 내면화했을 것입니다. . 프로그램을 읽거나 작성할 때마다 self 당신의 마음 뒤에 있습니다.

그러나 경험이 부족한 Rubyists의 경우 self 당황할 수 있습니다. 항상 변경되지만 코드에 명시적으로 표시되지는 않습니다. 당신은 단지 알 것으로 예상됩니다.

초보자가 직면하는 많은 문제는 self를 이해하지 못해서 발생합니다. . 인스턴스 변수를 "잃어버린" 적이 있거나 믹스인에 표시되는 데이터에 대해 의아해한 적이 있다면 self를 이해하지 못했기 때문입니다. 그 맥락에서.

이 게시물에서는 self를 살펴보겠습니다. 다양한 일상 상황에서.

self이란? ?

Ruby의 모든 것이 객체라는 말을 들어보셨을 것입니다. 그것이 사실이라면 작성하는 모든 코드 조각이 어떤 객체에 "속한다"는 의미입니다.

self 현재 실행 중인 코드를 "소유"하는 개체를 가리키는 특수 변수입니다. Ruby는 self를 사용합니다. 어디에서나:

  • 인스턴스 변수의 경우:@myvar
  • 메소드 및 상수 조회용
  • 메소드, 클래스 및 모듈을 정의할 때.

이론적으로 self 꽤 분명합니다. 그러나 실제로는 까다로운 상황이 발생하기 쉽습니다. 그것이 내가 이 포스트를 쓴 이유입니다.

self의 예

이제 몇 가지 예를 살펴보겠습니다. 첫 번째 내용이 너무 기초적인 것 같으면 계속 읽으십시오. 그들은 더 발전합니다.

인스턴스 메소드 내부

아래 코드에서 reflect 인스턴스 메서드입니다. Ghost.new를 통해 생성한 객체에 속합니다. . 그래서 self 해당 개체를 가리킵니다.

class Ghost
  def reflect
    self
  end
end

g = Ghost.new
g.reflect == g # => true

클래스 메소드 내부

이 예의 경우 reflect Ghost의 클래스 메소드입니다. . 클래스 메서드를 사용하면 클래스 자체가 메서드를 "소유"합니다. self 클래스를 가리킵니다.

class Ghost
  def self.reflect
    self
  end
end

Ghost.reflect == Ghost # => true

모듈 내부의 "클래스" 메서드와 동일하게 작동합니다. 예:

module Ghost
  def self.reflect
    self
  end
end 
Ghost.reflect == Ghost # => true

클래스와 모듈은 Ruby에서 객체로 취급된다는 것을 기억하십시오. 따라서 이 동작은 첫 번째 예제에서 본 인스턴스 메서드 동작과 크게 다르지 않습니다.

클래스 또는 모듈 정의 내부

Rails와 같은 프레임워크에 잘 맞는 Ruby의 한 가지 기능은 클래스 및 모듈 정의 내에서 임의의 코드를 실행할 수 있다는 것입니다. 클래스/모듈 정의 안에 코드를 넣으면 다른 Ruby 코드처럼 실행됩니다. 유일한 차이점은 self의 값입니다. .

아래에서 볼 수 있듯이 self 정의 중인 클래스 또는 모듈을 가리킵니다.

class Ghost
  self == Ghost # => true
end 

module Mummy
  self == Mummy # => true
end 

내부 믹스인 메소드

혼합 메서드는 self와 관련하여 "일반" 인스턴스 또는 클래스 메서드처럼 작동합니다. . 이것은 의미가 있습니다. 그렇지 않으면 믹스인이 믹스한 클래스와 상호 작용할 수 없습니다.

인스턴스 메소드

reflect하더라도 메소드가 모듈에 정의되었습니다. self 혼합된 클래스의 인스턴스입니다.

module Reflection
  def reflect
    self
  end
end 

class Ghost
  include Reflection
end

g = Ghost.new
g.reflect == g # => true

클래스 메소드

extend할 때 클래스 메소드에 혼합할 클래스, self 일반 클래스 메서드에서와 똑같이 동작합니다.

module Reflection
  def reflect
    self
  end
end 

class Ghost
  extend Reflection
end

Ghost.reflect == Ghost # => true

메타클래스 내부

한 번에 많은 클래스 메서드를 정의하는 이 인기 있는 바로 가기를 본 적이 있을 것입니다.

class Ghost
  class << self 
    def method1
    end

    def method2
    end
  end
end

class << foo 구문은 실제로 꽤 흥미롭습니다. 이를 통해 "싱글톤 클래스" 또는 "고유 클래스"라고도 하는 개체의 메타클래스에 액세스할 수 있습니다. 향후 포스트에서 메타클래스를 더 깊이 다룰 계획입니다. 그러나 지금은 메타클래스가 Ruby가 특정 객체에 고유한 메서드를 저장하는 곳이라는 것을 알아야 합니다.

self에 액세스하는 경우 class << foo 내부에서 블록, 당신은 메타 클래스를 얻습니다.

class << "test"
  puts self.inspect
end

# => #<Class:#<String:0x007f8de283bd88>

클래스 외부

클래스 외부에서 코드를 실행하는 경우 Ruby는 여전히 self를 제공합니다. . Object의 인스턴스인 "main"을 가리킵니다. :

puts self.inspect # => main