Consider the following example: you have a function framed
producing a cell with a button that, when pushed, calls framed
again. How to supply options to framed
such that whenever the button is pushed, the "embedded" framed
inherits these options? If, however, the framed
is called not by the button, it should use the default options (as it cannot inherit it from a parent).
The following example works as expected (any new cell will inherit a -> 1111
:
Options[framed] = {a -> 1};
Options[button] = {"framedOptions" -> Options@framed};
button[x_, opts : OptionsPattern[]] :=
Button[x, Print@framed[x, OptionValue@"framedOptions"]];
framed[x_, opts : OptionsPattern[]] :=
Framed[{button[x, "framedOptions" -> Flatten@{opts}], OptionValue@a}];
Print@framed["Push", a -> 1111];
Pushing the displayed button yields a second cell with inherited options:
But for certain reasons I want to avoid unnecessary options like "framedOptions"
and use some kind of scoping as there could be multiple embeddings and recursion and I don't want to forward "framedOptions"
all the time. No scoping would work however, as the button funcion is only evaluated at runtime.
Options[framed] = {a -> 1};
button[x_] := Button[x, Print@framed@x];
framed[x_, opts : OptionsPattern[]] := Framed[
Internal`InheritedBlock[{framed = framed},
SetOptions[framed, Flatten@{opts}];
{button@x, OptionValue@a}
]];
Print@framed["Push", a -> 1111];
Note that the problem extends to attributes or any part of a function definition. What I would really need is an InheritedDynamicBlock
(nonexistent) that not justs inherits the function definition but also keeps it local to a certain part of the screen (where the original content is displayed). Any idea?