Ну, Dumper
должен сказать вам, что $point3d
теперь Point
, а не Point3D
, потому что ваше присвоение $point3d = $point1
делает $point3d
второй ссылкой на тот же объект, что и $point1
, Экземпляр Point3D
, на который изначально ссылалась $point3d
, теперь теряется в пространстве с повторным счетом 0, что делает его пригодным для сбора мусора.
Как сказал cdhowie, вы на самом деле не делаете типотипирование в Perl так, как в C / C ++. Самое близкое, о чем я могу подумать, - это прибегнуть к соглашению о вызовах не-OO и использовать, например, Point3D::z($point1, 4)
, чтобы дать $point1
z-index 4, но это довольно неуклюже, и вам придется использовать тот же синтаксис для любых будущих ссылок на его z-index. Также обратите внимание, что при использовании этого соглашения о вызовах Point3D
должен фактически определять метод z
[1], иначе вы получите ошибку времени выполнения, потому что наследование не работает, когда вы делаете это таким образом потому что вы ссылаетесь на Point3D
как на пакет, а не на $point1
как на объект.
Если вы действительно хотите превратить Point
в Point3D
, вы можете легко изменить фактический тип объекта, используя bless
(та же самая команда, используемая для преобразования простой ссылки в объект в первую очередь). , хотя это скрыто внутри Moose в вашем примере кода), но я подозреваю, что ручная отбрасывание объекта Moose вызвало бы гнев Moose. (Но если это так, я уверен, что Moose предоставляет более безопасный способ изменения класса объекта. Я просто недостаточно использую Moose, чтобы знать, что это будет.)
[1] ... или AUTOLOAD
, но это совсем другая банка червей.