Nil에서 모든 메소드를 호출 할 수 있으며 이것이 잘못 느껴집니다.


14

최근에 스크립트를 디버깅하는 데 상당한 시간을 보냈으며 마침내 문제를 발견했을 때 다음과 같은 코드 때문이었습니다.

class Foo {
    has $.bar;
    method () {
        # do stuff
        $!.bar;
    }
}

그것은 문제가 그와 함께했다 판명 $!.bar중 하나 있었어야하는, $!bar또는 $.bar. 나는 이것을 얻는다.

그러나 왜 이것이 죽지 않습니까?

더 자세하게 살펴보면, 여기 문제처럼 보인다 나는 (존재하지 않는) 메소드를 호출하는 것을 시도하고 있다는 것입니다 bar$!이 시점에서, Nil오류가 없었던 때문입니다.

그리고 실제로 내가 원하는 모든 메소드를 호출 할 수있는 것처럼 보이며 Nil모두 and Nil같은 것을 포함하여 모두 자동으로 반환 됩니다.Nil.this-is-a-fake-methodNil.reverse-entropy(123)

이것이 기능입니까? 그렇다면 근거는 무엇입니까?

답변:


13

그것은 의도되고 문서화되어 있습니다. 제목 Nil은 "값 없음 또는 양성 실패"이며 클래스 문서에 언급되어 있습니다.

Nil존재하지 않는 메소드를 호출하면 결과적으로 서브 스크립팅 조작이 성공하고 리턴 Nil됩니다.

say Nil.ITotallyJustMadeThisUp;  # OUTPUT: «Nil␤» 
say (Nil)[100];                  # OUTPUT: «Nil␤» 
say (Nil){100};                  # OUTPUT: «Nil␤»

개요 2 는 " Nil반환시 정의되지 않은 메소드 호출 Nil이므로 Nil메소드 호출 체인 을 전파합니다. Nil리턴 에 대한 첨자 조작과 마찬가지로 Nil"이므로 의도는 모든 단계에서 $foo.Bar()[0].Baz()검사를 요구하지 않는 등의 표현식을 허용하는 것 같습니다. Nil"메소드 호출 및 첨자 연산자.


4
과연. 그리고 꽤 오래 전에 이미 github.com/rakudo/rakudo/commit/174727377f (2013 년 12 월) 참조 : design.raku.org/S02.html#Nil
Elizabeth Mattijsen

1
@ElizabethMattijsen 아, 나는 S02가 답을 가지고 있다고 생각합니다. "정의되지 않은 모든 메소드 호출은를 Nil반환 Nil하므로 Nil메소드 호출 체인을 아래로 전파합니다." 따라서 $foo.Bar().Baz().Blah()모든 단계 또는 특수한 ?.종류의 연산자에서 (마지막으로 nil을 올바르게 처리 하는 한) nil 테스트를 수행하지 않고도 할 수 있습니다 . 편집 해 드리겠습니다. 감사합니다.
홉스

1
Nil오류 및 그냥 더 발생하지 않는이 Nil의 Obj-C과는 유사한 방식으로 사용 년대 NS 프레임 워크에서 매우 광범위하게 사용을 얻는다 - 무기 호에 통과 계속 체인 통화를 할 수 있습니다. 예외의 정확한 성능 페널티를 파악하고 포착하는 것은 알 수 없지만 Nil유연하지 않으면 체인이 더 효율적일 수 있습니다.
user0721090601

1
(그러나 그것은 완전히 알려지지 않은 추측이므로, lizmat 또는 jnthn이 내가 틀렸다고 말해야한다는 것을
알게되어 기쁘다.

2
Nil클래스에는 FALLBACK docs.raku.org/language/typesystem#index-entry-FALLBACK_(method) 메소드 가 있으며이 메소드는을 리턴합니다 Nil. 기본적으로 메소드를 찾을 수 없어서 예외가 발생하기 직전에 점검 FALLBACK이 수행되고 사용 가능한 경우 호출됩니다.
Elizabeth Mattijsen

5

이 질문에 (그리고 홉스 '답)도 느끼게 ... 불안했다 : 나는 결국 발견 https://docs.raku.org/language/traps : 그것은 그 할당이 설명 Nil일반적으로 다른 값을 생성합니다 Any. 다음과 같은 기본 REPL 상호 작용도이를 보여줍니다.

> my $foo = Nil
(Any)

> $foo.bar
No such method 'bar' for invocant of type 'Any'
  in block <unit> at <unknown file> line 1

> my $bar := Nil
Nil

> $bar.baz
Nil

((차이 =와는 :=여기 피복 https://docs.raku.org/language/containers#Binding ))

... 일반적인 아이디어는 '결석 가치 또는 양성 실패'가 정규 코드에서 나보다 훨씬 덜 널리 퍼져 있다는 것입니다. 에 직접 호출하는 방법과 관련된 특정 우발적 상황에서 직접 일치 합니다$! .

이로 인해 Nil와 의 차이점에 대해 더 많이 알게 Any되었고 제공된 근거가 더 의미가 있습니다.


2
Nil컨테이너를 기본 상태로 설정합니다. 기본값을 변경할 수 있습니다. my $foo is default(42) = 5; $foo = Nil; say $foo; # 42
브래드 길버트
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.