3

I store a reference to the association in a held expression in a variable:

a=<||>;
b=Hold[a];

And in the code, I want to do manipulations with the original variable a including using methods that have HoldFirst attribute.

AssociateTo[b,"test"->1];
(* this obviously does not work *)

AssociateTo[ReleaseHold@b,"test"->1];
(* this does not either *)

Question is, how do I use b in AssociateTo[] to associate the value to the original globally-defined a association?

To clarify, my use case is that I store data in a nested Association stored as CloudExpression and create references ("indexes") of the values inside this association as Hold[] constructs. This works perfectly fine until I get to use the HoldFirst-set methods.

Update:

I was able to implement the desired behaviour using the ugly

AssociateToHold[assoc_,data_]:=
  ReleaseHold@
    Replace[
      Hold[AssociateTo[where,what]]/.
        {HoldPattern[where]->Unevaluated[assoc],HoldPattern[what]->data},
      Hold[x_]:>x,{2}
    ]
Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
grandrew
  • 550
  • 2
  • 10

2 Answers2

2

Here is one way:

associateToHold[Hold[v_], data_] := AssociateTo[v, data]

associateToHold[b, "test" -> 1]

(* <| "test" -> 1 |> *)

a

(* <| "test" -> 1 |> *)

We could do the same thing inline:

b /. _[v_] :> AssociateTo[v, "test" -> 1]

... or use a function with HoldFirst:

Function[Null, AssociateTo[#, "test" -> 1], HoldFirst] @@ b
WReach
  • 68,832
  • 4
  • 164
  • 269
1

This question is a variation of Elegant manipulation of the variables list.
The bump function I defined therein can be used here, e.g.

AssociateTo[bump[b, 1], "test" -> 1];

a
<|"test" -> 1|>

If you feel daring you can overload the system function like this:

Unprotect[AssociateTo];

AssociateTo[s_Symbol, defs_] /;
  MatchQ[OwnValues[s], {_ :> Hold[_Symbol]}] :=
    s /. Hold[ss_] :> AssociateTo[ss, defs]

Now this works as desired:

AssociateTo[b, "test" -> 1]

Reference: Injecting a sequence of expressions into a held expression

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371