Let's say I want to track any assignment attempt for a variable a:
a /: Set[a, x_] := Print@{a, x}
This works as intended:
a = 5
(* {a,5} *)
a
(* a *)
However, this doesn't catch the {...}={...} syntax:
({a, b} = {1, 2})
(* {1, 2} *)
a
(* 1 *)
And the following obviously does not work:
a /: Set[{___, a, ___}, x_] := Print@{a, x}
TagSetDelayed::tagpos: Tag a in {___, a, ___} = x_ is too deep for an assigned rule to be found.
(* $Failed *)
This leads to the following two questions:
- Is there any way to "nice" way to achieve such functionality? (By "nice" I mean something similar to assigning the definition to the upvalues of
a, as opposed to e.g.UnprotectingList/Setand attaching the definition there) - Why does
Setnot simply "thread" over the lists to give upvalue definitions a chance to catch the assignment? As it stands, this potentially breaks many "smart" symbols (e.g. file backed symbols) if the user ever decides to use the list assignment syntax. Is there anything what would not work if this would be the case?
Setis probably internal. There are a few ways you could work around this, depending on what you need done, but none that use exactly this syntax, I think. – b3m2a1 Sep 18 '17 at 23:02Protect[a]. – Carl Woll Sep 19 '17 at 14:56