“at”Sigil (@)은 루비 기능 내에서 어떤 범위를 제공합니까?
문제
내가 마지막으로 루비 프로그래밍을 한 지 오래되었습니다. 다른 사람의 코드를 보면 @
함수의시길 (~ 아니다 메소드 - 모든 클래스 정의 외부), 인스턴스 멤버에게 범위를 가진 것으로 이해되었습니다.
묵시적 모듈입니다 self
기능에서?
해결책
최상위 기능 (여전히 메소드)에서는 약간 이상한 장소에 있습니다 : 글로벌 "메인"공간 (실행할 때 프롬프트 참조 irb
, 또는보십시오 self
이러한 함수 내부)이지만 이러한 기능은 내부의 개인 메소드로 정의됩니다. Object
수업.
$ cat foo
def foo
p self
p self.class
puts 'foo'
end
foo
Object.foo
$ ruby foo
main
Object
foo
foo:8: private method `foo' called for Object:Class (NoMethodError)
$
이 방법을 명시 적으로 선언함으로써이 문제를 몰래 몰래 들어갈 수 있습니다. public
,하지만 나는 이것을 좋아하는지 확신하지 못한다! 흥미롭게도, 당신이 내부의 최상위 방법을 정의하면 irb
, 그런 다음 클래스 방법을 통해 호출 할 수 있습니다. Object#foo
공개적으로 선언하지 않고.
그래서 이것은 일종의 "암시 된 메인 네임 스페이스입니다. Object
(그러나 Shhh는 아무에게도 말하지 않습니다) ". @foo
최상위 함수 내부에서 정의 된 객체 내부는 일반 기존 속성으로 사용할 수 있습니다. 일종의. 최상위 메소드가 설정된 경우 @foo
그리고 당신은 그것을 범위를 지키지 않고 그것을 부릅니다. main
네임 스페이스이지만 클래스 메소드를 통해 전화하는 경우 Object
그 다음에 @foo
공간에 나타납니다 Object
.
또 다른 예:
public
def set_foo
@foo = 'foo'
end
def get_foo
@foo
end
def Object.get_foo_again
@foo
end
set_foo
p get_foo
p Object.get_foo_again
Object.set_foo
p Object.get_foo_again
주어진
"foo" # @foo set in main
nil # @foo nil in Object
"foo" # @foo in Object
대화도 적용됩니다.
다른 팁
이것이 "방법이 아닌 함수"라는 가정은 잘못된 것입니다. 모든 루비 코드는 일부 객체의 맥락에서 발생합니다. "글로벌"컨텍스트는 호출되는 객체입니다 main
(노력하다 ruby -e "puts self"
당신이 그것을 믿지 않는다면). 상단 범위에 정의 된 메소드는 인스턴스 메소드가됩니다. 이것은 방법을 사용할 수 있음을 의미합니다 어딘가에, 와 함께 self
(따라서 인스턴스 변수가 속한 컨텍스트) 메소드가 호출되는 위치에 따라
나는 그것이 모듈로 범위를 띠고 있다고 생각합니다.
@ 변수를 인스턴스 변수로 만듭니다. 그것은 명백하게 선언 된 클래스의 일부가 아닌 것 같습니다. 따라서 척이 지적한 것처럼 메인 객체 내에서 사용할 수 있습니다. 예를 통해 더 쉽게 설명합니다.
$ irb
irb(main):001:0> @var = 1
=> 1
irb(main):002:0> class New
irb(main):003:1> def test
irb(main):004:2> puts @var
irb(main):005:2> end
irb(main):006:1> end
=> nil
irb(main):007:0> test = New.new
=> #<New:0xb7ccbc14>
irb(main):008:0> test.test
nil
=> nil
irb(main):009:0> def test2
irb(main):010:1> puts @var
irb(main):011:1> end
=> nil
irb(main):012:0> test2
1
=> nil