Function Repository Resource:

 InheritedBlock

Source Notebook

Similar to Block, except values of local symbols are not cleared when entering the block

Contributed by: Richard Hennigan (Wolfram Research)

ResourceFunction["InheritedBlock"][{x,y,…},expr]

specifies that expr is to be evaluated with changes to the symbols x,y,… localized to the block.

ResourceFunction["InheritedBlock"][{x=x0,…},expr]

defines initial local values for x,….

Details and Options

ResourceFunction["InheritedBlock"] allows you to set up an environment in which the values of variables can temporarily be changed while keeping their initial values intact.
ResourceFunction["InheritedBlock"] is like Block, but values assigned to x, y, … are not cleared when entering the block.
When the execution of the block is finished, the original values of these symbols are restored.
ResourceFunction["InheritedBlock"] affects only the values of symbols, not their names.
ResourceFunction["InheritedBlock"] has attribute HoldAll.
ResourceFunction["InheritedBlock"] implements dynamic scoping of variables.

Examples

Basic Examples (3) 

Make temporary changes to the value of a symbol:

In[1]:=
x = 1;
ResourceFunction["InheritedBlock"][{x}, x = 2; x]
Out[2]=

The original value is restored:

In[3]:=
x
Out[3]=

Temporarily modify definitions of a function:

In[4]:=
f[x_] := x + 1;
ResourceFunction["InheritedBlock"][{f}, f[5] = "No!"; f /@ Range[10]]
Out[5]=

The changes to the definition of f only persisted within the block:

In[6]:=
f /@ Range[10]
Out[6]=

Make temporary changes to multiple symbols:

In[7]:=
{x, y} = {1, 2};
ResourceFunction["InheritedBlock"][{x, y}, {x, y} = {3, 4}; x + y]
Out[8]=

Both symbols are restored:

In[9]:=
{x, y}
Out[9]=

Scope (2) 

Modify Protected functions for one evaluation:

In[10]:=
ResourceFunction["InheritedBlock"][{Reverse},
 Unprotect[Reverse];
 HoldPattern[Reverse[xyz]] = zyx;
 Reverse /@ {{1, 2, 3}, xyz, {a, b, c}}
 ]
Out[10]=

The normal behavior is unchanged:

In[11]:=
Reverse /@ {{1, 2, 3}, xyz, {a, b, c}}
Out[11]=

The Attributes are restored as well:

In[12]:=
Attributes[Reverse]
Out[12]=

Temporarily change the default formatting of expressions:

In[13]:=
ResourceFunction["InheritedBlock"][{Graphics},
 Unprotect[Graphics]; FormatValues[Graphics] =.;
 MakeBoxes[Graphics[a_, b___], StandardForm] := RowBox[{"Graphics", "[", MakeBoxes[a, StandardForm], ",", ToBoxes[Iconize[Sequence[b], "Options"]], "]"}];
 Table[Echo[
   Graphics[{RandomColor[], Disk[]}, ImageSize -> 25, Background -> RandomColor[]]], 3]
 ]
Out[13]=

Applications (2) 

Have cloud deployments that would otherwise be deployed to anonymous cloud objects go to a specific target:

In[14]:=
ResourceFunction["InheritedBlock"][{CloudObject},
 Unprotect[CloudObject];
 CloudObject[] = CloudObject["temp"];
 CloudDeploy[APIFunction[{}, DateList[] &]]
 ]
Out[14]=

The normal behavior is unchanged:

In[15]:=
CloudDeploy[APIFunction[{}, DateList[] &]]
Out[15]=

Properties and Relations (2) 

InheritedBlock localizes values only; it does not create new symbols:

In[16]:=
x = 1;
ResourceFunction["InheritedBlock"][{x}, x =.; Print[x]]
In[17]:=
x
Out[17]=

Module creates new symbols:

In[18]:=
Module[{x}, Print[x]]

Possible Issues (3) 

Using Condition in InheritedBlock does not work the same way as Block, Module and With:

In[19]:=
g[1] := Block[{x = Echo[1]}, x /; False];
g[2] := Module[{x = Echo[2]}, x /; False];
g[3] := With[{x = Echo[3]}, x /; False];
g[4] := ResourceFunction["InheritedBlock"][{x = Echo[4]}, x /; False];
g /@ Range[4]
Out[20]=

The behavior is also different for held replacements:

In[21]:=
Hold[1, 2, 3] /. n_Integer :> Block[{x = n + 1}, x /; True]
Out[21]=
In[22]:=
Hold[1, 2, 3] /. n_Integer :> Module[{x = n + 1}, x /; True]
Out[22]=
In[23]:=
Hold[1, 2, 3] /. n_Integer :> With[{x = n + 1}, x /; True]
Out[23]=
In[24]:=
Hold[1, 2, 3] /. n_Integer :> ResourceFunction["InheritedBlock"][{x = n + 1}, x /; True]
Out[24]=

Symbols cleared with ClearAll within an InheritedBlock will not be restored:

In[25]:=
x = 1;
ResourceFunction["InheritedBlock"][{x}, ClearAll[x]];
x
Out[23]=

Compare to Block, which protects its symbols from ClearAll:

In[26]:=
x = 1;
Block[{x}, ClearAll[x]];
x
Out[27]=

Clear is safe to use:

In[28]:=
x = 1;
ResourceFunction["InheritedBlock"][{x}, Clear[x]];
x
Out[29]=

Requirements

Wolfram Language 11.3 (March 2018) or above

Version History

  • 1.0.0 – 14 March 2019

Related Resources

License Information