开发者

Print Dynamic variable inside DynamicModule

开发者 https://www.devze.com 2023-04-12 13:04 出处:网络
Why is it that not the value of b gets printed in the following example but the symbolname? How can I force the printing of the actual dynamic value of the variable?

Why is it that not the value of b gets printed in the following example but the symbolname? How can I force the printing of the actual dynamic value of the variable?

a = {1, 2, 3};

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

output:

b$107

Out[2]= {{3, 4, 5}, 3}

Edit (after reading your answers/comments):

Consider the more simple example, without Initialization code (to get around WReach's example):

a = {1, 2, 3};

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

output:

During evaluation of In[4]:= b$602

Out[5]= {{1, 2, 3}, 3}

Note, that this example does what I want to 开发者_JAVA百科if I use Module instead of DynamicModule or leave out Dynamic from the Print line. My concerns are:

  1. Why does this second example fail to print the value of b correctly? There is no Initialization, which (according to the help) contains "an expression to evaluate when the DynamicModule is first displayed". Also according to help: "When DynamicModule is first evaluated, initial assignments for local variables are made first, and then any setting for the Initialization option is evaluated."

  2. The help should read: "Initialization: an expression to evaluate when the result of DynamicModule is first displayed", meaning that a Print statement onscreen does not constitute 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 appears correctly.


I believe this happens because the Dynamic object b has not been displayed at the time the Print statement is called, and therefore the initialization has not been made. As I recall, Dynamic functionality does not operate until it is actually, visibly displayed.

See Why won't this work? Dynamic in a Select for more information.


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

One may see from the example below that the assignment RHS evaluation takes place before the body Print, at least by measure of the display order in the FrontEnd. Further, we see that Print "goes inside" Dynamic and takes the unique symbol name created by DynamicModule, and prints that. We can use ToString to cause Print to display the entire expression as it is. Likewise, if we extract the symbol name from that string, and convert it to an actual symbol, before printing, we get the expected value that has indeed already been assigned.

alarm := (Print["Initialized!"]; 3)

DynamicModule[{b = alarm},
  Print @ ToString @ Dynamic @ b;
  Print @ Symbol @ StringTake[ToString@Dynamic@b, {9, -2}];
  Print @ Dynamic @ b;
];

Output:

Initialized!

Dynamic[b$701]

3

b$701 


The crucial behaviour is described under the More Information section of the documentation for DynamicModule:

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

The exact sequence of events becomes more apparent if you add a Print statement to the Initialization option, thus:

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

The cell containing b$107 is the result of the Print inside the DynamicModule. Then, we get the result cell (tagged Out[7] here). Finally, we see the third cell output by Print statement in the Initialization.

If you inspect the cell expression of the Out[7] cell, 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 attributable to the "double scoping" described in the DynamicModule documentation. The b$107 cell contains a Dynamic box, as can be seen if we assign a value to b$107.

Update

In response to the updated question...

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

First, the body of the DynamicModule is evaluated after giving "unique names to local variables [...] just like 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 containing b$107 is created but that cell is now removed from further consideration as it is not part of the result of the evaluation. Now, "a version of [{Dynamic[a], Dynamic[b$107]}] is wrapped in DynamicModule" and returned. This is evaluated and implicitly printed to produce an output cell expression like this:

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 particularly that b$107 is renamed to $CellContext`b$$ as a function of DynamicModule symbol localization. The Initialization expression is now evaluated as the box is displayed and visible.

The key point is that the printed cell containing b$107 is not coupled in any way to the final DynamicModule cell.

0

精彩评论

暂无评论...
验证码 换一张
取 消