# 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 – Leonid Shifrin 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. – m_goldberg Dec 2 '12 at 1:07
Strongly related: (1), (2) – Mr.Wizard 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. – Cuboid 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. – Artes 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:

Using pure functions in Table

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

-