Ruby에서 모듈의 인스턴스 변수를 초기화하려면 어떻게해야합니까?


80

인스턴스 변수를 사용하고 싶은 모듈이 있습니다. 현재 다음과 같이 초기화하고 있습니다.

module MyModule
  def self.method_a(param)
    @var ||= 0
    # other logic goes here
  end
end

초기화하기 위해 init 메서드를 호출 할 수도 있습니다.

def init
  @var = 0
end

그러나 이것은 항상 그것을 부르는 것을 기억해야한다는 것을 의미합니다.

이 작업을 수행하는 더 좋은 방법이 있습니까?


3
첫 번째 코드 블록은 모듈 인스턴스 변수 (MyModule의 유형 개체 범위에있는 변수)를 설정하고 두 번째 코드 블록은 "일반"인스턴스 변수 (모듈을 포함하는 인스턴스 범위의 변수)를 설정하지 않습니까? 나는이 두 코드 블록이 같은 일 ...하지 않는 생각
보리스 B.

답변:


109

모듈 정의에서 초기화하십시오.

module MyModule
  # self here is MyModule
  @species = "frog"
  @color = "red polka-dotted"
  @log = []

  def self.log(msg)
    # self here is still MyModule, so the instance variables are still available
    @log << msg
  end
  def self.show_log
    puts @log.map { |m| "A #@color #@species says #{m.inspect}" }
  end
end

MyModule.log "I like cheese."
MyModule.log "There's no mop!"
MyModule.show_log #=> A red polka-dotted frog says "I like cheese."
                  #   A red polka-dotted frog says "There's no mop!"

모듈이 정의 될 때 인스턴스 변수를 설정합니다. 나중에 alwasys가 모듈을 다시 열어 인스턴스 변수와 메서드 정의를 더 추가하거나 기존 변수를 재정의 할 수 있습니다.

# continued from above...
module MyModule
  @verb = "shouts"
  def self.show_log
    puts @log.map { |m| "A #@color #@species #@verb #{m.inspect}" }
  end
end
MyModule.log "What's going on?"
MyModule.show_log #=> A red polka-dotted frog shouts "I like cheese."
                  #   A red polka-dotted frog shouts "There's no mop!"
                  #   A red polka-dotted frog shouts "What's going on?"

12
오래되었지만 그래 :). 또한 Messrs Foo and Bar에 대해 말해야 할 모든 것이 언급되었다고 생각합니다.
rampion

그렇다면이 시점에서 인스턴스 변수가 아니라 인스턴스 메서드입니까?
nipponese 2014 년

nipponese : 인스턴스 변수가 아닌 것은 무엇 입니까?
rampion 2014 년

5

당신이 사용할 수있는:

def init(var=0)
 @var = var
end

그리고 아무것도 전달하지 않으면 기본값은 0입니다.

매번 호출 할 필요가없는 경우 다음과 같이 사용할 수 있습니다.

module AppConfiguration
   mattr_accessor :google_api_key
   self.google_api_key = "123456789"
...

end

그래서, 모듈을 사용하기 전에이 함수를 호출해야합니까?
Geo

나는 그 문제를 피하기 위해 두 번째 방법을 추가했다 – 그것의 레일 코드에서
Brian

2

클래스의 경우, 클래스의 새 인스턴스를 .new 할 때마다 초기화가 호출되기 때문에 다음과 같이 말할 것입니다.

def initialize
   @var = 0
end

에서 실제 루비 :

계속해서 포함 클래스의 초기화가 super를 호출하면 모듈의 초기화가 호출되지만 이것이 초기화를위한 특별한 처리가 아니라 모든 곳에서 super가 작동하는 방식의 결과라고 언급하지 않습니다. (초기화가 특별한 처리를받는다고 가정하는 이유는 무엇입니까? 가시성과 관련하여 특별한 처리를 받기 때문입니다. 특수한 경우는 혼란을 야기합니다.)


1
모듈이기 때문에 초기화가 호출됩니까? 그것이 나의 첫 번째 대답이었습니다. 나는 그것이 호출되지 않는 것을 설명하기 위해 두 번째를 추가했습니다.
Brian

1
영업 이익은 특히 모듈이 아닌 클래스 언급 한
Zensaburou

2

비슷한 질문 에 대답했습니다. 이 작업을 수행하여 클래스 인스턴스 변수를 설정할 수 있습니다.

module MyModule
  class << self; attr_accessor :var; end
end

MyModule.var
=> nil

MyModule.var = 'this is saved at @var'
=> "this is saved at @var"

MyModule.var    
=> "this is saved at @var"

2

분명히 Ruby의 모듈에서 인스턴스 변수를 초기화하는 것은 잘못된 형식입니다. (이유로 나는 완전히 이해하지 못하지만 사물이 인스턴스화되는 순서와 관련이 있습니다.)

가장 좋은 방법은 다음과 같이 지연 초기화와 함께 접근자를 사용하는 것 같습니다.

module MyModule
  def var
    @var ||= 0 
  end
end

그런 다음 사용 var에 대한 게터로 @var.


4
이에 설정 @var 당신을 허용하지 않습니다 참고 nil또는false
스틸
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.