Print Dynamic Variable inside DynamicModule

Why doesn't this b value get printed in the following example besides the character? How to force the printing of the actual dynamic value of a variable?

a = {1, 2, 3}; DynamicModule[{b}, Print[Dynamic[b]]; {Dynamic[a], Dynamic[b]} , Initialization :> (b = Length[a]; a = a + 2) ] 

exit:

 b$107 Out[2]= {{3, 4, 5}, 3} 

Edit (after reading your answers / comments):

Consider a simpler example without the Initialization code (to get around the WReach example):

 a = {1, 2, 3}; DynamicModule[{b = Length[a]}, Print[Dynamic[b]]; {Dynamic[a], Dynamic[b]} ] 

exit:

 During evaluation of In[4]:= b$602 Out[5]= {{1, 2, 3}, 3} 

Note that this example does what I want if DynamicModule use Module instead of DynamicModule or leave Dynamic in the Print line. My problems:

  • Why can't this second example print the value of b correctly? There is no initialization, which (according to the help) contains "an expression for evaluation at the first display of DynamicModule". Also according to: "When DynamicModule is evaluated first, initial assignments for local variables are made first, and then any setting for the Initialization parameter is evaluated."

  • On the right you should read: "Initialization: an expression to evaluate when the result DynamicModule displayed for the first time, "which means that the Print statement on the screen is not the" result "of the DynamicModule . If this is correct, then (and only then) I understand why the Print statement does not mean that the Dynamic object is displayed correctly.

+6
source share
2 answers

The decisive behavior is described in the "More Information" section of the documentation for DynamicModule :

DynamicModule first gives unique names to local variables in expr expressions, like a module, then evaluates the resulting expression, and then returns the version of this package to DynamicModule.

The exact sequence of events becomes more apparent if you add a Print statement to the Initialization parameter, this way:

 a = {1, 2, 3}; DynamicModule[{b}, Print[Dynamic[b]]; {Dynamic[a], Dynamic[b]} , Initialization :> (b = Length[a]; Print["init:", b]; a = a + 2) ] 

resulting in three cells:

  b$107 Out[7]= {{3, 4, 5}, 3} init:3 

A cell containing b$107 is the result of Print inside a DynamicModule . Then we get the result cell (marked Out[7] here). Finally, we see the output of the third cell in the Print expression in Initialization .

If you check the cell expression of the Out[7] cell Out[7] , you will find that the localized variable is b$$ . This is different from the variable in the first cell, which is b$107 . This difference is due to the โ€œdouble coverageโ€ described in the DynamicModule documentation. Cell b$107 contains the Dynamic field, as you can see if we assign the value b$107 .

Update

In response to an updated question ...

Returning to the original expression (without additional Print in Initialization ), the exact sequence of events is as follows:

First, the body of the DynamicModule is evaluated after providing "unique names to local variables [...] just like a module". That is, this expression is evaluated:

 Print[Dynamic[b$107]]; {Dynamic[a], Dynamic[b$107]} 

The result of this expression is the list {Dynamic[a], Dynamic[b$107]} . As a side effect, a dynamic cell is created containing b$107 , but this cell is now removed from further consideration, since it is not part of the evaluation result. Now "the version of [ {Dynamic[a], Dynamic[b$107]} ] is wrapped in a DynamicModule" and is back. This is evaluated and implicitly printed to create an expression of the output cells as follows:

 Cell[BoxData[ DynamicModuleBox[{$CellContext`b$$ = 3}, RowBox[{"{", RowBox[{ DynamicBox[ToBoxes[$CellContext`a, StandardForm], ImageSizeCache->{57., {2., 8.}}], ",", DynamicBox[ToBoxes[$CellContext`b$$, StandardForm], ImageSizeCache->{7., {0., 8.}}]}], "}"}], DynamicModuleValues:>{}, Initialization:>($CellContext`b$$ = Length[$CellContext`a]; $CellContext`a = $CellContext`a + 2)]], "Output"] 

Note that b$107 renamed to $CellContext`b$$ as a function for localizing the DynamicModule character. The expression Initialization now evaluated as the window is displayed and displayed.

The key point is that the print cell containing b$107 is not connected in any way with the last DynamicModule cell.

+3
source

I believe this happens because the Dynamic b object was not displayed at the time the Print statement was called, and therefore the initialization was not completed. As far as I remember, Dynamic functionality does not work until it actually appears on the display.

See Why this does not work? Dynamic in Select for more information.


In response to your update, my theory is that the Dynamic statement in Print never displays FrontEnd, and so it never gets initialized. That is, it remains a unique placeholder, waiting to be filled with the dynamic value of b when it is finally displayed.

In the example below, you can see that the destination RHS is evaluated in front of the Print body, at least as it is displayed in the FrontEnd. Further we see that Print "enters" Dynamic and accepts the unique symbol name created by DynamicModule and prints it. We can use ToString to call Print to display the entire expression as is. Similarly, if we extract the name of a character from this string and convert it to an actual character, before printing we get the expected value that has actually been assigned.

 alarm := (Print["Initialized!"]; 3) DynamicModule[{b = alarm}, Print @ ToString @ Dynamic @ b; Print @ Symbol @ StringTake[ ToString@Dynamic @b, {9, -2}]; Print @ Dynamic @ b; ]; 

Conclusion:

  Initialized!

 Dynamic [b $ 701]

 3

 b $ 701 
+6
source

Source: https://habr.com/ru/post/899076/


All Articles