parser

Написать ответ на текущее сообщение

 

 
   команды управления поиском

[ Рафинировал код ] "Посмертный опыт объекта" - наводящей ясности таки прибавило, спасибо. Хотя и спрашивал немножко про другое.

andylars 15.04.2016 13:21 / 15.04.2016 13:35

В общем и целом, мне изначально понятно, что отвязывается именованная ссылка (имя объекта/переменной) от одного экземпляра класса, и назначается другому (новому).

Меня больше интересовали подводные грабли "посмертного опыта" у старого объекта в конкретном частном случае при вот таком вкладывании объектов и при вот таком каноническом обращении.

Сейчас уже "утопталось" в голове получше, и стало очевидно где можно поймать грабли.

Решил максимально рафинировать суть.

В общем, получается, такая схема
$MAIN
     \
      $obj <App_class>
          \
            $App    <self>
              |              
              +- $Sub(1) <Sub_class>
              |  # который, по ходу своего выполнения просит наверх у $App,
              |  # пересоздать себе другой, новый $Sub
              |  # этот экземпляр продолжает жить своей жизнью, хоть и отвязывается от канонической ссылки
              |
              +- $Sub(2) <Sub_class>
                 # новый экземпляр закрепленный по канонической ссылке $App.Sub
Выводы, которые я пока сделал.
При таком "ребилде" каскада вложенных объектов, по инициативе "снизу",
надо осознано подойти либо к контролю дальнейшего исполнения кода в этом инициаторе.

Либо понимать, что если дальше по коду встретится работа с объектами и методами по каноническому обращению
типа
$App.Sub.Field
- то это будет не обращение к своим полям, а обращение к полям уже нового объекта
т.е. общение со своим "актуальным" двойником из своего "мира мёртвых". Это может быть даже каким-то осознаным действием, когда надо что-то допередать своему будущему клону... но может и породить грабли.

И поэтому в местах, где должно отрабатываться только в контексте себя, надо применять обращения на уровне контекста только своего экземпляра, в рамках своего класса, для это есть просто
$self.Sub.Field
В общем это то, что у меня "утряслось" пока.

Disclaimer: пример кода, опять же, пишу сразу в textarea (не проверял, но кажется, что именно так и будет). Одновременно, кажется еще и "удачный" наглядный пример, когда метод конструктора работает не только как синтаксис для создания объекта, но и повторный вызов как динамического метода.
@main[]
  $trigger(true)
  $session[^App_class::create[]]

#----------------------------------------

@CLASS
App_class

@create[]
  $self.App[$self]
  $self.Sub[^Sub_class::create[$self.App]]


#----------------------------------------

@CLASS
Sub_class

@create[_parent]
  $self.App[$_parent]

  $self.Random(^math:random(999))
  $self.App.Sub.Random   ^rem{# выдаст к примеру 123  }

  ^if($MAIN:trigger){
     $MAIN:trigger(false)
     ^self.App.create[]
  }

  $self.App.Sub.Random   ^rem{# выдаст уже 456, т.к. он обратился на самом деле к другому экземпляру  }
  $self.Random           ^rem{# по-прежнему хранит 123 }  

#----------------------------------------
P.S.: И да, существует способ "убить" старый экземпляр $Sub(1) в данном примере?