2
$\begingroup$
DynamicModule[{totalpages, pagesize},
 StringJoin[{"of ", ToString@totalpages, "."}],
 Initialization :> (pagesize = 5; 
   totalpages = Ceiling[Length[Range[456]]/pagesize];)
 ]

(* "of totalpages$443602." *)

As I understand DynamicModule, totalpages will be created from the scoping list when the code is executed. Then before the output is first displayed the Initialization option code will be executed which should set a value to totalpages. Finally the output will be displayed.

However, the result I appear to be getting is that the Initialization code is not being called; only the scoping code. Or perhaps it is being called after the output is displayed. In any case I'm not getting the expected result.

What have I misunderstood?

It is interesting that the following works. However I can't use a pagesize variable in this case.

DynamicModule[{totalpages = Ceiling[Length[Range[456]]/5]},
 StringJoin[{"of ", ToString@totalpages, "."}]
 ]

(* "of 92." *)

Version 10.2 - Will be installing 10.3 later this week.

$\endgroup$
5
$\begingroup$

The behaviour we see is due to the fact that the expression referencing totalPages has dynamic dependencies, but it is not wrapped in Dynamic itself. The simple fix is to add Dynamic in front of StringJoin:

DynamicModule[{totalpages, pagesize},
 Dynamic@StringJoin[{"of ", ToString@totalpages, "."}],
 Initialization :> (pagesize = 5; 
   totalpages = Ceiling[Length[Range[456]]/pagesize];)
 ]

(* of 92. *)

However, it is much more interesting to examine the aspects of DynamicModule that explain the peculiar results we see. In particular, the exhibited expressions reveal some of the localization strategies used at different stages of the DynamicModule evaluation process.

Discussion

For the discussion that follows, we will use an expression that reveals three important stages that occur during DynamicModule evaluation:

DynamicModule[{x, y = "y-eval"}
, {ToString[x], x, Dynamic[x], ToString[y], y, Dynamic[y]}
, Initialization :> (x = "x-init"; y = "y-init")
]

(* {"x$123", x$$, "x-init", "y-eval", "y-eval", "y-init"} *)

The results "x$123", x$$ and "x-init" correspond to the three stages in question. An outline of the sequence of events is as follows.

Stage 1: Initial Evaluation

As per the documentation of DynamicModule, the expression is first evaluated after localizing all variables as if by Module. This generates the symbols x$123 and y$123. Only latter is assigned a value.

The body of the DynamicModule is evaluated with these bindings in place. ToString[x] captures the normally unobservable symbol name x$123 in a string:

(* {"x$123", x$123, Dynamic[x$123], "y-eval", "y-eval", Dynamic[y$123]} *)

Stage 2: Placeholder Localization

The preceding result will be used to build the actual dynamic boxes. Any local variables are renamed again to become so-called "placeholders":

(* { "x$123", $CellContext`x$$, Dynamic[$CellContext`x$$],
 "y-eval", "y-eval", Dynamic[$CellContext`y$$] } *)

Placeholders are necessary because a rendered DynamicModule can be duplicated by copy-and-paste, each copy needing to use different variables. Placeholders are replaced by such unique variables when rendered for display.

Stage 3: Display

When the DynamicModule becomes visible, the placeholders are resolved, and the initialization form is evaluated. Both x$$ and y$$ receive values, but only Dynamic parts of the expression will reflect those values. That is why we see the final result which, when rendered, shows the non-dynamic reference to the placeholder x$$ as an unevaluated symbol:

(* {"x$123", x$$, "x-init", "y-eval", "y-eval", "y-init"} *)


The present response has glossed over some details in the interest of brevity. There are more than three stages, and some of the stages operate upon box forms instead of the simple expressions shown above. (75323) discusses some of those details in more depth.

$\endgroup$
1
$\begingroup$

//InputForm is often helpful as well in a user is uncertain about what is happening

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.