# Set does not work

I tried following code, but it does not work as expected:

Do[Set[a[[1]],a[[2]]],{a,{x->2,y->5,z->x+y}}]

{x,y,z}


I want the result to be {2,5,7}, but it becomes just {x,y,z}. I tried a[[1]]=a[[2]] instead of Set[a[[1]],a[[2]]], but it does not work too.

I tried the following code, and it works well:

hoge[x_, y_] := x = y
Do[hoge[a[[1]],a[[2]]],{a,{x->2,y->5,z->x+y}}]
{x,y,z}


But this needs extra function and is not so smart. Does anyone have a good idea?

• Quick fix: Do[Set @@ a, {a, {x -> 2, y -> 5, z -> x + y}}] but it will fail anyway, as soon as x/y/z have values. related: 28610, also see links in 103628
– Kuba
May 16, 2017 at 9:07
• Thanks a lot, Kuba. It worked. And I found that in the first code I set the first element of list a with a[[2]], and it is the failure. May 16, 2017 at 9:43
• Related, and recommended reading: (280), (6511), (6669), (10322) Jun 2, 2017 at 7:06

Set is specially overloaded for Part in order to allow in-place modification of the expressions:

a = x -> 2;
a[[1]] = 1; a

1 -> 2


It is documented on the Documentation page for Part (the first point under "Details" section):

You can make an assignment like t[[spec]]=value to modify any part or sequence of parts in an expression. »

Your function hoge doesn't Hold its arguments and hence passes to Set the extracted variable (a Symbol) instead of the Part expression what explains why it "works" for you:

hoge[x_, y_] := Hold[x = y]
a = x -> 2;
hoge[a[[1]], a[[2]]]

Hold[x = 2]


For your particular purpose the simplest approach is to replace Rule by Set:

Clear[x, y, z]
{x -> 2, y -> 5, z -> x + y} /. Rule -> Set

{2, 5, 7}


Another method is to Apply Set effectively replacing the head Rule by Set:

Clear[x, y, z]
Set @@@ {x -> 2, y -> 5, z -> x + y}

{2, 5, 7}


Inside of Do:

Clear[x, y, z]
Do[Set @@ a, {a, {x -> 2, y -> 5, z -> x + y}}];
{x, y, z}

{2, 5, 7}