# Button's command is not evaluated in iteration

I wish I didn't feel like a newbie after several months, but...

If I enter the following:

Table[ Button[ "Number: " <> ToString @ i, Print @ i], {i, 1, 5}]


this creates a list of buttons, labelled Number: 1, Number: 2, etc. but pressing each button only prints i, not the number corresponding to the button. I assume this is standard newbie-doesn't-understand Mathematica stuff, but would appreciate any explanation of how to change the behaviour so that each button prints the value of i.

• Very closely related question Dec 1 '12 at 18:44
• Don't feel bad -- it took me a rather embarrassing long time to realize Button's HoldRest attribute required I use With to get the kind of behavior you are looking for. Dec 2 '12 at 1:07
• Strongly related: (1), (2) Jan 12 '13 at 13:46

You could do

Table[
With[{i = i}, Button["Number: " <> ToString@i, Print@i]],
{i, 1, 5}]


The reason is that

Attributes@Button



so that the code you produce ends up containing things like Button["Number: 2", Print[i]] (try looking at Table[Button["Number: " <> ToString@i, Print@i],{i, 1, 5}] // FullForm to see this). With literally replaces i with the value at each iteration, even if the expression is held (as it is here).

• Many thanks, that's a great link too. Dec 1 '12 at 18:37

Since your parameter i in Button is outside Table (because of the HoldRest attribute of Button), it is not a number anymore. However you could do e.g. this :

Button["Number: " <> ToString @ #, Print @ #] & /@ Range[5]


If there is a need for i parameter one can do this :

Button["Number: " <> ToString @ #, Print @ # ] & /@ Table[i, {i, 5}]

• I guess the question really is "how does i end up outside the Table" (answer, because Button is HoldRest)
– acl
Dec 1 '12 at 18:42
• The question was : How to change the behaviour so that each button prints the value of i ? I didn't need the reasoning concerning the attributes of Button, my answer explains how to do what the OP wanted. Dec 1 '12 at 19:07
• OK, my apologies then. Note that your code works precisely because it circumvents the attributes (i gets evaluated to a number outside the Button, so HoldRest can't prevent it), so I don't see how you don't need the HoldRest bit.
– acl
Dec 1 '12 at 19:27

You can do :

Table[With[{i = i}, Button["Number: " <> ToString@i, Print[i]]], {i, 1, 5}]


I favor Array here:

Array[Button[Row @ {"Number: ", #}, Print @ #] &, 5]


Also see:

Function in Table

How do you properly create Buttons to change dynamic variables using Table