1
$\begingroup$

How can I do the following? I have code inside a Module such as Module[{a1,a2,a3,a4}, code...]. In this code I want to refer to these constants efficiently (for a large number of them) so I would construct them in ways such as Table[ToExpression["a" <> ToString[i]], {i, 4}]. The important point is that they are constructed as a1 (etc) after the module has done its renaming to a unique variable. So this does not work, see:

Module[{a1}, 
 MemberQ[Table[ToExpression["a" <> ToString[i]], {i, 3}], a1]]

Is it possible to do this correctly? (By the way, this is almost the opposite question of Refering to global variables inside modules.)


As often, the time needed to formulating the question was enough to actually find a solution. While it isn't an answer to the question, the better way to avoid the whole problem is to assign multiple downvalues to one a , i.e. a[1],a[2],...

$\endgroup$
  • 1
    $\begingroup$ maybe Block instead of Module? $\endgroup$ – kglr Jul 14 '17 at 12:13
  • $\begingroup$ @kglr, thanks. I think I'd also consider this a full answer. Indeed not only does this work, I think it is the sensible solution. I have been following the advice of the wise Leonid Shifrin: "In practice, my advice would be to avoid using Block unless you know quite well why you need it." However, I do think that this is the type of situation that actually calls for a Block. Your answer inspired me to finally read up on Block, instead of dismissing it as less useful than Module. $\endgroup$ – Kvothe Jul 14 '17 at 15:07
  • $\begingroup$ Kvothe, I posted the comment as an answer. $\endgroup$ – kglr Jul 14 '17 at 15:19
2
$\begingroup$

Using Block instead of Module:

Block[{a1}, MemberQ[Table[ToExpression["a" <> ToString[i]], {i, 3}], a1]]

True

From Block >> Properties and Relations:

  • Block localizes values only; it does not create new symbols

  • Module creates new symbols

$\endgroup$
3
$\begingroup$

It can be done using $ModuleNumber. However a[1], a[2],... is better

Module[{a1, a2, a3, mn = $ModuleNumber},
 MemberQ[Table[ToExpression[
    StringJoin["a", ToString[i], "$", ToString[mn]]], {i, 3}], a1]]

True

Note, if $ModuleNumber is called outside the local brackets it needs to be decremented.

Module[{a1, a2, a3, mn},
 mn = $ModuleNumber - 1;
 MemberQ[Table[ToExpression[
    StringJoin["a", ToString[i], "$", ToString[mn]]], {i, 3}], a1]]

True

$\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.