El código dado en este hilo ya no funciona: ¿Cómo puedo rebadificar un objeto en Perl 6?
Escribí este código el año pasado, y funcionó entonces. Ahora no lo hace:
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
El mensaje de error no tiene sentido, ya que se supone que funciona con clases heredadas. Al menos lo fue.
La documentación no es útil; https://docs.raku.org/routine/rebless
Respuestas:
Nunca se suponía que fuera tan general. Diseñé esa API y la implementé en primer lugar, y solo pretendía ser un detalle de implementación de mixins.
Hasta hace muy poco, no formaba parte del conjunto de pruebas de especificación de lenguaje, y cuando se convirtió en parte de él, ya tenía su semántica actual, más restrictiva. Las restricciones son importantes por razones de rendimiento: cuando sabemos que un tipo no es uno que puede ser el objetivo de una operación mixin, podemos compilar JIT los accesos de atributos en ese objeto en algo mucho más simple (pagamos un movimiento condicional adicional en cada atributo accede antes del cambio, y ahora solo tiene que pagarlo en los tipos de destino mixin).
Es posible modificar el programa original para que funcione utilizando el MOP para construir la clase. De hecho, el siguiente no es el programa original; Hice un pequeño ajuste con el fin de mostrar cómo se pueden proporcionar métodos en la subclase como un rol anónimo, para evitar demasiado repetitivo MOP.
Si bien esa es la solución semánticamente directa al programa original, hay una forma más corta: use el
but
operador en elPerson
objeto de tipo para producir un tipo de mezcla y devolverlo, y luego simplemente modifique su nombre a su gusto:Que es solo una línea extra que la original de todos modos.
fuente
constant Woman = Person but role …
No me di cuenta de que eso se podía hacer. ¡Y por lo tanto, pero para laBEGIN
línea, Raku casi logra ser capaz de hacer un paradigma prototípico de estilo JS también!class
palabra clave , citando nuevamente S12: "por defecto, los objetos derivados deMu
un modelo basado en clases bastante estándar ...bless
... llama ... rutinas BUILD ... la semántica BUILD predeterminada es heredado deMu
". En resumen, diría que es más exacto decir que Raku admite A) "deformar seriamente incluso el OO basado en clase estándar con solo un par de líneas de código" y B) "OO basado en prototipo".Vea la respuesta de jnthn para una discusión autorizada sobre exactamente qué sucedió
rebless
y qué hacer al respecto.Puede valer la pena leer esta respuesta (¡muy larga!) Para aquellos interesados en una discusión más profunda de los principios y la práctica del enfoque TDD que subyace al trabajo en el lenguaje de programación Raku y los artefactos relacionados, como el compilador Rakudo y el contenido docs.raku.org .
Esta respuesta está estructurada como respuestas específicas a partes particulares de la pregunta original de Arne y de los comentarios que escribieron en respuesta a una versión anterior de esta respuesta. Mi intención era hacerlo más útil para Arne mientras, con suerte, seguir siendo útil para los demás.
He actualizado la respuesta aceptada a ese SO para vincular a este SO.
El cambio relevante se discutió en una confirmación de abril de 2019 en la que jnthn escribió:
En un comentario hace 11 días cerrando el problema rakudo GH "Rebless a un tipo personalizado ya no parece funcionar" , escribió:
(Haga clic en el enlace de arriba para obtener notas sobre cómo hacer lo que sugiere).
Este problema también se discute un poco más en el sentido de que funcionó ... de repente no ... la documentación ... debe documentar la sección de llamadas a continuación.
asado - el r epository o f una ll s pec t EST - determina lo que se supone código Raku hacer. (El st de roa st puede leerse como s upposed t o s.)
En otro mensaje de abril de 2019, jnthn escribió:
El hecho de que el comportamiento de Rakudo sea especificado por un conjunto de pruebas ejecutables es una parte fundamental del enfoque de @Larry para garantizar que Raku se comporte de manera confiable [1] y tenga profundas implicaciones [2] .
El impacto de este cambio en un módulo ampliamente utilizado
Aquí hay una instantánea del impacto de este cambio que se desarrolla para el popular módulo Inline :: Perl5.
En abril de 2019, niner abrió un problema rakudo GH sobre el impacto
Inline::Perl5
y he extraído algunos aspectos destacados del intercambio entre niner y jnthn a continuación.(He eludido algunas cosas que eran importantes en el contexto original, pero que distraen en el contexto de este SO. No suponga que comprende completamente la conversación original de este extracto. En caso de duda, haga clic en el enlace. )
Ayudando con los documentos
En un comentario debajo de esta respuesta que has escrito:
Eso me parece una respuesta muy apropiada y útil al problema en el corazón de su SOQ. Espero que tengamos la suerte de que esto suceda.
Imo, su redacción técnica es excelente, así que espero que el resultado final de su trabajo con otras personas involucradas en mejorarlo sea algo maravilloso.
Restricciones fundamentales sobre el contenido de docs.raku.org
Una gran parte de la razón por la que escribí el resto de esta respuesta tan extensa a una pregunta aparentemente tan simple, y la restablecí después de eliminarla inicialmente una vez que Jonathan la había respondido, fue para discutir los principios y la práctica del enfoque TDD que subyace en el trabajo el lenguaje de programación Raku y los artefactos relacionados, como el compilador Rakudo y el contenido docs.raku.org .
Aiui, la relación deseable entre cómo se supone que funcionan las cosas en Raku, y cómo funcionan realmente en Rakudo, y cómo se supone que las cosas deben documentarse en docs.raku.org se reduce a:
Se DEBE presumir que todo está sujeto para siempre a la naturaleza fundamental de un proyecto voluntario; y, dentro de esa restricción:
El comportamiento en el asado DEBE estar documentado y el otro comportamiento NO DEBE.
(Dado el tiempo voluntario disponible, el interés y el consenso, ocasionalmente se hacen excepciones para documentar el comportamiento de un Rakudo de control de calidad adecuado que no está cubierto por el asado. En la práctica actual, esto parece significar el comportamiento de una versión de Rakudo en un Rakudo Star lanzado).
Documentación inútil
Lo consideré un comentario justo. A fin de cuentas, la documentación tal como estaba cuando escribió su pregunta no fue útil.
Esta es una afirmación muy diferente.
No había entrada de asado cubriendo
rebless
en ese momento.Si la página docs.raku.org
rebless
hubiera descrito su comportamiento tal como era en 2018, entonces eso hubiera sido peor que inútil porque sugeriría incorrectamente que el comportamiento actual era compatible. En realidad, había margen para que se rompiera en una versión futura de Rakudo sin una perspectiva razonable de que el comportamiento de 2018 sería restablecido por los desarrolladores principales. Y, de hecho, esto sucedió: su comportamiento no compatible a partir de 2018 se rompió y no fue restablecido.Entonces, dado el consenso sobre lo que pertenece en docs.raku.org y lo que no (ver arriba), lo más útil que
rebless
podría hacer su página era no documentarrebless
en absoluto o, quizás mejor, incluir una página para ello, pero asegúrese de que no describió su comportamiento. Cuál era la situación: la página existía; no fue directamente útil; y eso fue posiblemente mejor que nada.(Es fácil imaginar que las cosas mejoren aún. Por ejemplo, ¿qué pasaría si las funciones de documentación de páginas incluyeran un porcentaje que documentara el estado de la cobertura de prueba asociada con esa función en la versión de Rakudo en la última Rakudo Star? Un 0% podría dar pistas de inmediato a un lector en una conciencia de que esa función no estaba cubierta por el asado. Dicho esto, si bien esta función de documentación es fácil de imaginar , ¿quién la implementará? Es igualmente fácil imaginar que podría llevar un año calendario o más de trabajo diligente y colaboración para implementar e implementar de manera útil, y que la gente piense que otras cosas son más importantes).
funcionó ... de repente no ... la documentación ... debería documentar la llamada
Fue "suerte" que funcionó.
Porque Rakudo fue mejorado.
Como se explicó anteriormente, todo el consenso de la comunidad actual y / o práctica de trabajo es: la documentación DEBE documentar una versión particular de la llamada, a saber, el comportamiento de tostado para la versión de Rakudo en la última Rakudo Star; y PUEDE documentar el comportamiento en otras versiones.
Aiui, el consenso actual y / o práctica de trabajo es que lo que algunos podrían considerar contribuciones de documentos "débiles", por ejemplo, algún contenido breve y escrito apresuradamente y / o enlaces fuera de los documentos, PUEDE introducirse si los voluntarios sienten que se justifica un cambio inmediato para reflejar alguna preocupación planteada por un usuario (por ejemplo, este SO) y que hacer el cambio "débil" sería mejor que no hacer nada en absoluto. Por supuesto, puede hacer un RP para mejorarlo (o revertirlo si realmente siente que un cambio es tan "débil" que empeora las cosas).
(También es algo así por mi cuenta, aunque he visto un compilador que dice ser 2019.03.1 con la misma interrupción en el comportamiento. [3] )
Creo que JJ hizo el cambio de documento y simplemente malinterpretó el comentario de Jnthn sobre cómo adaptarse al cambio. Actualmente creo que es mejor que nada, pero espero que lo actualices. :)
Notas al pie
[1] Lo siguiente se dijo unos minutos después de que Larry anunciara por primera vez el proyecto que llevó a Raku en su discurso de 2000 "El estado de la cebolla" :
[2] Por supuesto, el asado solo funciona bien para un usuario dado si sus pruebas cubren suficientemente las necesidades del usuario. El problema de Arne demuestra cómo los agujeros en la cobertura pueden ser sorprendentes. Para una discusión sobre estos agujeros tal como estaban en 2018, consulte Especificaciones, versiones, cambios y ... Rotura . La buena noticia es que el asado es solo un montón de pruebas unitarias escritas en Raku para probar que las expresiones o construcciones con valores particulares hacen algo en particular. Por lo tanto, es fácil para las personas o empresas contribuir con nuevas pruebas para mejorar la cobertura de las pruebas. Y todo está bajo control de versiones (git), por lo que las etiquetas, ramas y horquillas posteriores personalizadas son viables, sostenibles y manejables. (De hecho, eso es cómo las nuevas versiones de idioma (
Christmas
,Diwali
,Eid
(?), Etc.) se gestionan.)[3] He visto un intento de rechazar una nueva clase creada usando la
newclass is oldclass
sintaxis regular, tanto funciona (en mi computadora portátil) como no funciona (en repl.it) usando compiladores que dicen ser2019.03.1
. (Presumbly repl.it instaló una versión del código fuente del compilador, o un binario compilado a partir de él, tomado de la cabeza maestra poco después de actualizar la versión del compilador2019.03.1
, con el cambio de ruptura en su lugar. Noto que repl.it haven ' No publiqué su respuesta de raku en línea, lo descubrí por accidente, por lo que no hay nada desagradable en esta situación, pero me reforzó la necesidad del$RAKU.compiler.verbose-config
método utilizado en los resultados trabajados / rotos que acabo de vincular.fuente
Pregunta de seguimiento: vea Raku rebless y múltiples clases
fuente