Raku rebless는 더 이상 상속 된 클래스와 작동하지 않습니다


9

이 스레드에 제공된 코드는 더 이상 작동하지 않습니다. Perl 6에서 객체를 어떻게 복원 할 수 있습니까?

작년 에이 코드를 작성했는데 그때 작동했습니다. 이제는 그렇지 않습니다.

class Person { ; }
class Woman is Person { ; }
my $tom = Person.new;
my $lisa = Woman.new;

say $tom.^name;  # -> Person
say $lisa.^name; # -> Woman

Metamodel::Primitives.rebless($tom, Woman);
# -> New type Woman for Person is not a mixin type

상속 된 클래스와 함께 작동해야하므로 오류 메시지는 의미가 없습니다. 적어도 그랬습니다.

설명서는 도움이되지 않습니다. https://docs.raku.org/routine/rebless


회귀 버그 일 수 있습니다. 아마도 Rakudo 문제로보고하는 것이 가장 좋습니다.
jjmerelo

지난 2 월에 약간의 변화가있었습니다 : github.com/perl6/nqp/blob/…
jjmerelo

또한 @jnthn answer docs.raku.org/type/Metamodel::Primitives를 가리키는 각주로 설명서를 업데이트했습니다 . 감사합니다, raiph
jjmerelo

답변:


11

상속 된 클래스와 함께 작동해야합니다

결코 그렇게 일반적인 것이 아니 었습니다. 나는 그 API를 디자인하고 처음에 그것을 구현했으며, 믹스 인의 구현 세부 사항으로 만 사용되었습니다.

최근까지는 언어 사양 테스트 스위트의 일부가 아니 었습니다. 그리고 그 일부가되었을 때 이미 현재의보다 제한적인 의미론을 가지고있었습니다. 이것의 제약은 성능상의 이유로 중요합니다 : 타입이 mixin 연산의 대상이 될 수없는 것을 알면, 그 객체에 대한 속성 액세스를 훨씬 더 간단한 것으로 JIT 컴파일 할 수 있습니다 (추가 조건부로 지불했습니다) 변경 전에 모든 속성 액세스, 이제 믹스 인 대상 유형에 대해서만 지불해야합니다).

MOP를 사용하여 클래스를 구성하여 작동하도록 원래 프로그램을 수정할 수 있습니다. 실제로 다음은 원래의 프로그램이 아닙니다. 너무 많은 MOP 상용구를 피하기 위해 서브 클래스에서 메소드를 익명의 역할로 제공하는 방법을 보여주기 위해 약간의 조정을했습니다.

class Person { method m() { "person" } }
constant Woman = do {
    my \w = Metamodel::ClassHOW.new_type(:is_mixin, :name<Woman>);
    w.^add_parent(Person);
    w.^add_role(role { method m() { "woman" } });
    w.^compose()
}
my $tom = Person.new;
my $lisa = Woman.new;

say $tom.^name;  # -> Person
say $lisa.^name; # -> Woman

say $tom.m; # person
Metamodel::Primitives.rebless($tom, Woman);
say $tom.m; # woman

그것이 원래의 프로그램에 대한 가장 의미 적으로 직접적인 수정이지만, 더 짧은 방법이 있습니다 : type 객체 의 but연산자 Person를 사용하여 믹스 인 유형을 생성하고 반환 한 다음 원하는대로 이름을 조정하십시오.

class Person { method m() { "person" } }
constant Woman = Person but role { method m() { "woman" } }
BEGIN Woman.^set_name('Woman');

my $tom = Person.new;
my $lisa = Woman.new;

say $tom.^name;  # -> Person
say $lisa.^name; # -> Woman

say $tom.m;
Metamodel::Primitives.rebless($tom, Woman);
say $tom.m;

어쨌든 원본보다 한 줄만 더 있습니다.


constant Woman = Person but role …그것이 가능하다는 것을 몰랐다. 그리고 이렇게 만에 BEGIN선 라쿠 단지 프로토 타입 패러다임 너무 JS 스타일을 할 수있는 떼어에 대한!
user0721090601

확인. 설명 감사합니다. docs.raku.org/routine/rebless 는 꽤 쓸모가 없기 때문에 설명서에 들어가기를 희망합니다 ... 곧«Beginning Raku»를 업데이트 할 것입니다.
Arne Sommer

@ user0721090601 Raku는 S12 : "클래스 기반 및 프로토 타입 기반 OO 프로그래밍 모두"를 인용하여 지원합니다 . 그러나 키워드를 사용하여 객체를 생성하면class S12를 다시 인용합니다. "기본적 Mu으로 상당히 표준적인 클래스 기반 모델 을 지원하는 객체를 ... bless... 호출 ... BUILD 루틴 ... 기본 BUILD 시맨틱은 에서 상속되었습니다 Mu. 요약하자면, Raku가 A) "두 줄의 코드만으로 늪지 표준 클래스 기반 OO조차도 심각하게 뒤틀린" B) "프로토 타입 기반 OO"를 지원한다고 말하는 것이 더 정확하다고 주장합니다 .
레이프

변경 사항을 깨는 것에 대한 나의 견해는 raku-musings.com/reblessed.html 을 참조하십시오 .
Arne Sommer

5

정확히 무슨 일이 있었으며 어떻게해야하는지에 대한 권위있는 토론은 jnthn의 답변을 참조하십시오 rebless.

그것은 ... 작동하지 않습니다 .... 오류 메시지가 이해가되지 않습니다 ... 그것은 상속 클래스와 함께 작동해야합니다 ... 적어도 ... ... 문서는 도움이되지 않습니다

이 (초장!) 답변은 Raku 프로그래밍 언어 및 Rakudo 컴파일러 및 docs.raku.org 컨텐츠 와 같은 관련 아티팩트에 기초한 TDD 접근법 의 원리와 실제에 대한 추가 토론에 관심이있는 사람들에게 읽어 볼 가치가 있습니다. .

이 답변은 Arne의 원래 질문의 특정 부분과이 답변의 이전 버전에 대한 답변으로 작성한 의견에 대한 구체적인 답변으로 구성됩니다. 저의 의도는 Arne에게 더 유용하게 만드는 것이었지만 다른 사람들에게는 여전히 유용하기를 바랍니다.

Arne : 이 스레드에 제공된 코드가 더 이상 작동하지 않습니다. Raku에서 객체를 어떻게 축복 할 수 있습니까?

이 SO에 링크하기 위해 해당 SO에 대한 허용 된 답변을 업데이트했습니다.

Arne : 작년에이 코드를 작성했는데 그때 효과가있었습니다. 이제는 그렇지 않습니다

jnthn이 작성한 2019 년 4 월 커밋 에서 관련 변경 사항에 대해 논의했습니다 .

최근에는 rebless작업의 대상이 된 유형이 최적화를 지원하기 위해 mixin 대상 유형으로 명시 적으로 작성해야했습니다. ...

에서 "사용자 정의 형식이 더 이상 작동하는 것 같다에 Rebless"십일일 폐쇄 rakudo GH 문제 전 주석 , 그는 썼다 :

is_mixin명명 된 인수를 전달 하도록 준비해야 ClassHOW.new_type합니다. 클래스 구문을 사용하여이를 수행 할 방법이 없으므로 리브리스의 대상 유형도 MOP를 사용하여 어셈블해야합니다.

(제안하는 방법에 대한 정보는 위의 링크를 클릭하십시오.)

이 문제는 또한 조금 더 자세히 논의되었습니다 ... 갑자기 ... 문서가 아니 었습니다 ... 문서 아래에 통화 섹션을 문서화해야 합니다.

Arne : 상속 된 클래스와 함께 작동해야합니다. 적어도 그랬습니다.

로스트 - R epository FLL 상의 주머니 t ESTS - 라쿠 코드가 어떻게해야을 결정합니다. 합니다 ( 세인트 ROA 성이 로 읽을 수있는 S upposed t O S).

다른 2019 년 4 월 메시지에서 jnthn은 다음과 같이 썼습니다.

에 대한 이전 사양이 없습니다 Metamodel::Primitives.rebless. 나는 이 스펙을 추가하여 이제 존재합니다. 이것은 이제 작동 할 것으로 예상되는 것에 대한 정의가 있음을 의미합니다.

Rakudo의 동작이 실행 가능한 테스트 스위트에 의해 지정되었다는 사실은 Raku가 안정적으로 동작하도록하는 @Larry의 접근 방식의 근본적인 부분이며 [1] 심오한 의미가 있습니다 [2] .

이 변경이 널리 사용되는 모듈에 미치는 영향

다음은 널리 사용되는 Inline :: Perl5 모듈에서 이러한 변경 사항이 미치는 영향에 대한 스냅 샷입니다.

2019 년 4 월, niner은 그 영향에 대한 rakudo GH 이슈를Inline::Perl5 열었고, niner와 jnthn 사이의 교환에 대한 주요 내용을 아래에서 추출했습니다.

(원래 문맥에서 중요한 것들을 제거했지만이 문맥에서 혼란스러워합니다. 이 추출에서 원래 대화를 완전히 이해 했다고 가정하지 마십시오 . 의심 스러운 경우 링크를 클릭하십시오. )

아홉 번째 : TBH 내가 여기서하는 일은 아마 항상 비린내가 있었을 수도 있습니다 ... 심지어 그럴 수도 있습니다 ... 나는 그것을 제거 할 수 있습니다 ... 이미 배포 된 상태로 유지하는 것이 좋을 것입니다 인라인 : : Perl5 버전을 실행 .

jnthn : 에 대한 이전 사양이 없습니다 Metamodel::Primitives.rebless. [a] spectest를 추가하여 지금 존재합니다. 이것은 이제 작동 할 것으로 예상되는 내용과 어떤 Inline :: Perl5가 신뢰할 수 있는지에 대한 정의가 있음을 의미합니다.

알 수없는 명명 된 매개 변수는 무시되지만 :mixin이전 Rakudo 버전에서는 필요하지 않았으므로 이전 Rakudo 버전과 곧 출시 될 버전에서 작동 할 수있는 새로운 Inline :: Perl5 릴리스를 만들 수 있으므로 최소한있을 수 있습니다 역전.

기존 Inline :: Perl5 버전에서 작동하는 방법이 없다고 생각합니다 ...

niner : 불행히도 패스 :mixin는을 통해 생성 된 서브 클래스에서 수행되므로 도움이되지 않습니다 Metamodel::Primitives.create_type. 서브 클래스는 normal을 사용합니다 Perl6::ClassHOW.

나는 처음부터 반박 해킹을 제거하기 위해 주요 리 팩터를 작업하고 있습니다. 릴리스 관리자가 rakudo의 릴리스 후보에 대해 작동중인 Inline :: Perl5가 없음을 인식하고 있으므로이 문제를 다시여십시오.

jnthn : MOP를 사용하여 해당 클래스를 작성합니까? 당신은 전달할 수 :is_mixinPerl6::ClassHOW.new_type그렇다면.

아홉 번째 : 아니요,이 상황에 해당합니다.class Bar is Foo { }

문서 도움

이 답변 아래의 의견에서 당신은 작성했습니다 :

설명서 부분에 도움을 줄 수 있습니다

그것은 당신의 SOQ의 핵심에 문제에 대한 매우 적절하고 유용한 응답처럼 들립니다. 우리는 이것이 다가올만큼 운이 좋기를 바랍니다.

도움이된다면

Imo 당신의 기술적 인 글쓰기가 우수하므로 그것을 향상시키는 데 관련된 다른 사람들과 함께 일한 결과가 훌륭한 일이기를 바랍니다.

docs.raku.org의 내용에 대한 기본 제약

내가보기에 간단한 질문에 대한이 광범위한 답변의 나머지 부분을 작성하고 Jonathan이 대답 한 후 처음 삭제 한 후 복원 한 이유의 상당 부분 은 작업의 기본이되는 TDD 접근 방식 의 원리와 실제를 논의하는 것이 었습니다 . Raku 프로그래밍 언어 및 Rakudo 컴파일러 및 docs.raku.org 컨텐츠 와 같은 관련 아티팩트

Aiui는 일이 라쿠에 일을 생각하고, 실제로 Rakudo에서 어떻게 작동하는지, 사물이에 대해 문서화되어있을 방법 방법 사이의 바람직한 관계 docs.raku.org는 아래로 비등 :

  • 모든 것은 반드시 자원 봉사 프로젝트의 기본 성격에 영원히 대상이 될 것으로 추정된다; 그리고 그 제약 내에서 :

  • 로스트 에서의 행동은 문서화 되어야 하며 다른 행동은 금지되어야합니다.

(자원 봉사 시간, 관심사 및 합의에 따라 로스트에 포함되지 않은 올바르게 QA 된 Rakudo의 동작을 문서화하는 경우가 가끔 있습니다. 현재 실무에서 이는 릴리스 된 Rakudo Star에서 Rakudo 버전의 동작을 의미하는 것으로 보입니다.)

쓸모없는 문서

설명서가 도움이되지 않습니다

나는 이것을 공정한 의견이라고 생각했다. 모든 것을 고려했을 때, 당신의 질문을 썼을 때의 문서는 도움이되지 않았습니다.

그 문서는 쓸모가 없었다 [2018 년]

이것은 매우 다른 진술입니다.

당시 로스팅 항목이 없었 rebless습니다.

에 docs.raku.org 페이지 경우 rebless 했다가 이 2,018 있다는 동작을 설명, 그 다음이되었을 것이다 쓸모보다 더 나쁜 것이 잘못 당시 행동이 지원 제안했다 때문이다. 실제로 합리적인 전망없이 미래 버전의 라쿠도에서 벗어날 수있는 범위가있었습니다 .2018 행동은 핵심 개발자에 의해 회복 될 것입니다. 그리고 실제로 이것은 통과되었습니다 .2018 년부터 지원되지 않는 행동이 깨졌고 복직하지 못했습니다.

따라서 docs.raku.org에 속하는 내용과 그렇지 않은 내용에 대한 합의를 고려할 때 (위 참조) 해당 rebless페이지가 할 수 있는 가장 유용한 일은 전혀 문서화하지 않았 rebless거나 더 나은 페이지를 포함시키는 것이었지만 동작을 설명 하지 않았 는지 확인하십시오 . 상황은 다음과 같습니다. 페이지가 존재했습니다. 직접 도움이되지 않았다; 그리고 그것은 아무것도 아닌 것보다 낫습니다.

예를 들어, 최신 Rakudo Star의 Rakudo 버전에서 해당 기능과 관련된 테스트 범위 상태를 문서화하는 백분율을 포함하는 페이지가 함수를 문서화하는 페이지에 백분율이 포함되어 있다면 어떨까요? 이 문서 기능은 로스팅에 포함되지 않았다는 인식으로,이 문서 기능은 상상 하기 쉽지만 누가 구현할 것입니까? 역시 1 년 이상 부지런한 작업이 필요할 수 있다고 상상하는 것도 쉽습니다. 유용한 구현 및 배포를위한 공동 작업, 다른 사람들이 더 중요하다고 생각하는 사람들.)

그것은 작동했다 ... 그것은 갑자기하지 않았다 ... 문서화 ... 전화를 문서화해야

그것은 효과가 있었다

그것은 "행운"이었다.

갑자기 더 이상 작동하지 않았다

라쿠도가 개선 되었기 때문에.

문서 ... 전화를 문서화해야합니다

앞에서 설명한 바와 같이, 현재의 커뮤니티 합의 및 / 또는 실무 관행은 다음과 같습니다. 문서 특정 버전 의 호출, 즉 최신 Rakudo Star에서 Rakudo 버전에 대한 로스팅 동작을 문서화해야 합니다 . 다른 버전에서는 동작을 문서화 할 수 있습니다.

다른 것을 언급하지 않고

Aiui, 현재 합의 및 / 또는 실무 관행은 일부 "약한"문서 기여 (예 : 간략하고 서두르 게 작성된 콘텐츠 및 / 또는 문서 외부의 링크)를 고려할 수있는 것입니다. 사용자에 의해 제기 된 일부 우려 (예 :이 SO)와 "약한"변경은 아무 것도하지 않는 것보다 낫습니다. 물론 PR을 개선하여 개선 할 수 있습니다 (또는 변경이 너무 "약하다"고 생각하면 문제를 악화시키는 경우 되돌릴 수 있습니다).

2019.11의 변경 사항에 대한 언급은 내 계산에 의해 7 개월입니다.

(나의 계산에 의해서도 마찬가지입니다. 비록 컴파일러가 동일한 동작 중단과 함께 2019.03.1이라고 주장하는 것을 보았습니다. [3] )

JJ가 문서를 변경했다고 생각하고 변경에 적응하는 방법에 대한 jnthn의 의견을 잘못 해석했습니다. 나는 현재 그것이 아무것도 아닌 것보다 낫다고 생각하지만 그것을 업데이트하기를 기대합니다. :)

각주

[1] Larry가 2000 년“양파 상태”연설 에서 Raku로 이끈 프로젝트를 처음 발표 한 후 몇 분 후에 다음과 같은 내용이 언급되었습니다 .

질문 : [Raku]에 사양이 있습니까?

Larry : 우리가 특히 강조하고 싶은 것은 ... 현재 회귀 테스트를 개발하는 것만 큼 [언어 디자인] 사양이 아닐 것입니다. "이것은 [라쿠]이고, [라쿠]가 아닙니다"라고 말하면서 실제로 기계가 읽을 수있는 사양을 가지고 있습니다. 그리고 나에게 그것은 실제로 사람이 읽을 수있는 것의 언어가 말하는 것보다 훨씬 더 중요합니다.

[2] 물론 로스팅은 테스트가 사용자의 요구를 충분히 충족시키는 경우 주어진 사용자에게만 잘 작동합니다. Arne의 문제는 커버리지의 구멍이 얼마나 놀라운지를 보여줍니다. 2018 년에 있었던 이러한 구멍에 대한 자세한 내용은 사양, 버전 관리, 변경 및… 파손을 참조하십시오 . 좋은 소식은 로스트는 특정 값을 가진 표현이나 구조가 특정한 일을 하는지를 테스트하기 위해 Raku로 작성된 많은 단위 테스트라는 것입니다. 따라서 개인이나 기업이 테스트 범위를 개선하기 위해 새로운 테스트에 참여하는 것이 쉽습니다. 또한 모두 버전 제어 (git)하에 있으므로 맞춤형 다운 스트림 태그, 브랜치 및 포크는 실행 가능하고 지속 가능하며 관리 가능합니다. (사실, 즉 언어 버전 (어떻게 새로운 Christmas, Diwali, Eid(이?) 등) 관리됩니다.)

[3] 내가 정기적으로 사용하여 만든 새로운 클래스 rebless하기 위해 본 적이 newclass is oldclass구문 모두 (내 노트북에) 작업하지 (repl.it에) 일을 주장 할 수 있음을 컴파일러를 사용하여 2019.03.1. 아마도 repl.it은 컴파일러 버전이로 업데이트 된 직후 마스터 헤드에서 가져온 컴파일러 소스 코드 버전 또는 컴파일 된 바이너리 2019.03.1를 설치했습니다. t 그들의 온라인 raku repl을 공개했습니다-우연히 발견했습니다-그래서이 상황에 대해 아무 것도 없습니다 $RAKU.compiler.verbose-config.


: 나는 어떻게 "rebless"작품을 파악하려고 할 때 문서가 쓸모가 없었로서 나는이 문서를 발견 stackoverflow.com/questions/44486985/...을 그리고 다음했다. 그리고 갑자기 더 이상 작동하지 않았으며 문서는 여전히 쓸모가 없었습니다. 그것은 여전히 ​​전화를 문서화해야하며 다른 것을 언급하지 않아야하기 때문에 여전히 그렇습니다. 그리고 2019.11의 변경 사항에 대한 언급은 내 계산에 의해 7 개월입니다.
Arne Sommer

도움이된다면 설명서 부분을 도와 드릴 수 있습니다.
Arne Sommer

@ArneSommer 문서 도움말로 시작하는 내 답변의 새 섹션을 참조하십시오 .
raiph

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.