`Set` is specially [overloaded][1] 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`][2] (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} [1]: https://mathematica.stackexchange.com/a/55503/280 [2]: http://reference.wolfram.com/language/ref/Part.html