Bug introduced in V10.4 or earlier and persisting through V12.0
[CASE:3852725] was created
[...] I have forwarded an incident report to our developers with the information you provided. [...]
This small helper function will show us TaggingRules
written explicitly to the notebook. (Because Options/CurrentValue
show values merged from $FrontEnd/$FrontEndSession
too)
nbTR[] := TaggingRules /. List @@ Rest @ NotebookGet @ EvaluationNotebook[]
Here is the story:
create a new notebook and evaluate:
CurrentValue[$FrontEndSession, {TaggingRules, "a"}] = 1;
now we can check that notebook's
TaggingRules
are nicely merged even though they are not written explicitly:CurrentValue[EvaluationNotebook[], {TaggingRules, "a"}]
nbTR[]1
TaggingRules
Pay attention now! Let's use example from documentation: TaggingRules / Applications
So we want to have some tagging rules local to the notebook:
CurrentValue[
EvaluationNotebook[], {TaggingRules, "InputFieldState"}
] = "initial string";And let's check:
CurrentValue[EvaluationNotebook[], {TaggingRules, "InputFieldState"}]
"initial string"
but
nbTR[]
{......., "a" -> 1 (??!!), "InputFieldState" -> "initial string"}
So the bottom line is, if the notebook doesn't contain TaggingRules
explicitly then it will inherit all you have in $FrontEnd
/$FrontEndSession
!
And this is a problem because:
I didn't modify
"a"'s
value on a notebook level but it is now localized here and won't inherit external changes:CurrentValue[$FrontEndSession, {TaggingRules, "a"}] = 22;
CurrentValue[$FrontEndSession, {TaggingRules, "a"}]
CurrentValue[EvaluationNotebook[], {TaggingRules, "a"}]22
1 (!!!)
Not to mention that you write to file possibly private data without notice.
I consider this a serious flaw. Any suggested prevention measures?
Answer
The only solution I've found is to set empty Tagging
rules first:
CurrentValue[EvaluationNotebook[], TaggingRules] = {};
CurrentValue[ EvaluationNotebook[], {TaggingRules, "InputFieldState"}] = "initial string";
Which is fine enough for my purposes but this is ok only if the notebook was just created or you know that there aren't any TaggingRules
.
The problem of course appears when you don't know and you don't want to overwrite them with {}
. Options / CurrentValue
(Absolute
or not) will only tell you what is there with already included $FrontEnd
values, so to check what is explicitly written you have to call NotebookGet
, and it doesn't scale well as notebook size grows.
So to check you can run:
MemberQ[TaggingRules -> _] @ Rest @ NotebookGet[]
p.s. there is an undocumented syntax for CurrentValue
so that by using:
CurrentValue[$FrontEndSession, {TaggingRules, "test"}, 2]
we say "give me TaggingRules 'test' value and if it doesn't exist, set it to 2
and return 2
. Very convenient. But
CurrentValue[EvaluationNotebook[], TaggingRules, {}]
doesn't work in this case :)
Comments
Post a Comment