6
$\begingroup$

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]

?

$\endgroup$
  • $\begingroup$ 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.. $\endgroup$ – Silvia Apr 25 '13 at 20:11
  • 1
    $\begingroup$ @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 :-) $\endgroup$ – Leonid Shifrin Apr 25 '13 at 20:21
  • $\begingroup$ @LeonidShifrin It's this one I meant, looks like a bad memory, alerts me to go to sleep now :/ $\endgroup$ – Silvia Apr 25 '13 at 20:24
  • $\begingroup$ 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. $\endgroup$ – Mr.Wizard Apr 26 '13 at 2:04
  • $\begingroup$ @Leonid long overdue, but I finally referenced that answer in my own. At the time of writing I did not recall your use. $\endgroup$ – Mr.Wizard Apr 26 '13 at 2:29
6
$\begingroup$

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*)
| improve this answer | |
$\endgroup$
4
$\begingroup$

Here's something I found:

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

56

| improve this answer | |
$\endgroup$
  • 2
    $\begingroup$ 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 $\endgroup$ – Mr.Wizard Apr 26 '13 at 2:07
  • 2
    $\begingroup$ It should be noted that this does not use var but the Set expressions explicitly. Nevertheless it is instructive and my +1 stands. $\endgroup$ – Mr.Wizard Apr 26 '13 at 2:17
2
$\begingroup$
var /: Block[var, code_] := Block[{x = 2, y = 3, z = 4}, code]

So

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

(* 4 *)
| improve this answer | |
$\endgroup$
2
$\begingroup$

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

| improve this answer | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.