7

Is is possible to assign {x = 2, y = 3, z = 4} to a variable var so that one can write

Block[var, x*y*z]

(or similar) instead of

Block[{x = 2, y = 3, z = 4}, x*y*z]

?

u17
  • 601
  • 3
  • 8
  • If I remember right, I think there is a similar question with an excellent answer by @LeonidShifrin . Just can't recall the keywords right now.. – Silvia Apr 25 '13 at 20:11
  • 1
    @Silvia I answered a similar one here - perhaps, that's what you meant? One of the solutions I posed does use the injector pattern, although by that time it did not yet have this nice name :-) – Leonid Shifrin Apr 25 '13 at 20:21
  • @LeonidShifrin It's this one I meant, looks like a bad memory, alerts me to go to sleep now :/ – Silvia Apr 25 '13 at 20:24
  • While this is a simpler question than the linked duplicate as it does not start with strings, it is a subset of that question and also answered there. If anyone feels that this should not be closed please vote accordingly or respond to this comment. – Mr.Wizard Apr 26 '13 at 02:04
  • @Leonid long overdue, but I finally referenced that answer in my own. At the time of writing I did not recall your use. – Mr.Wizard Apr 26 '13 at 02:29
  • @Mr.Wizard Thanks, I do appreciate that, but I think you are responsible for really bringing this to widespread use, so it really does not matter that it was used in some answers before yours. In your answer, this was a central thing, and the question was asked specifically about it, while in other answers it was a technical trick to get something else working, and was just one of possible solutions there. – Leonid Shifrin Apr 26 '13 at 08:51
  • @Mr.Wizard I think the question is stated more clearly here and I think the answers here add something, but if you put Ajasja's observation in your answer I'd be happy :). – Jacob Akkerboom Apr 26 '13 at 11:11
  • @Jacob Pardon me, which observation? – Mr.Wizard Apr 26 '13 at 17:20
  • @Mr.Wizard I'm sorry I'll have to change my opinion (and add that it is of course humble). I don't like the examples with MapIndexed in a question that is supposed to more general than this one. Arf I'm stressed don't listen to me :) – Jacob Akkerboom Apr 26 '13 at 17:45
  • Almost a duplicate: (19758) – Mr.Wizard Nov 08 '19 at 08:52

4 Answers4

6

This could be another case for the injector pattern:

var = Hold@{x = 2, y = 3, z = 4}

var /. Hold[inj_] :> Block[inj, x*y*z]

(*24*)
?x
(*Global`x --- so we did not leak*)
Ajasja
  • 13,634
  • 2
  • 46
  • 104
5

Here's something I found:

With[{h := {x = 7, y = 8}},
 Block[h, x y]]

56

amr
  • 5,487
  • 1
  • 22
  • 32
  • 2
    That's an excellent application of this AFAIK-undocumented syntax. My old "injector pattern" answer was given specifically to handle cases where this method did not work (Sequence); in cases where it does it's surely easier to read for those not already acquainted with the "injector" or deeply familiar with replacement rules. +1 – Mr.Wizard Apr 26 '13 at 02:07
  • 2
    It should be noted that this does not use var but the Set expressions explicitly. Nevertheless it is instructive and my +1 stands. – Mr.Wizard Apr 26 '13 at 02:17
2

The way I prefer is

var := {x = 2, y = 3, z = 4}
ReleaseHold[Hold[Block[var, x*y*z]] /. OwnValues[var]]
x

-> 24

-> x

Or

Apply[Block, Hold[var, x*y*z] /. OwnValues[var]]
x

-> 24

-> x

For

hVars = Hold[{x = 2, y = 3, z = 4}];

We can do

ReleaseHold[Hold[Block][hVars, Hold[x*y*z]]]
x

-> 24

-> x

Jacob Akkerboom
  • 12,215
  • 45
  • 79
2
var /: Block[var, code_] := Block[{x = 2, y = 3, z = 4}, code]

So

x = 100;
Block[var, x + 2]

(* 4 *)
Rojo
  • 42,601
  • 7
  • 96
  • 188