(minor thread necro for the purpose of forum searches)
I ran into this same thing recently and thought I would add some reminders to the community's collective knowledge, i.e., Google.
In this code, there's a Blizzard scrollframe instantiating instances of (as arnath says) BlahBlahButtonTemplate. The scrollframe (call it BlahBlahContainer) is inheriting the HybridScrollFrameTemplate, which means that the created frames are stored in an array at BlahBlahContainer.buttons. It's not exactly good form to access that table by hand, sure, but there is no API available to make things neat.
Now by default, the relevant OnStuff handler from BlahBlahButtonTemplate is shared across all N created buttons. There's only a single copy of the function. Calling :HookScript creates a new function (think about it) which calls your own handler then calls what was there before. Calling :HookScript on each of the N instantiated buttons means that each one gets its own freshly-created copy of N identical wrapper functions, because there's no reasonable way for :HookScript to know that the new closure is the same as the one(s) you previously created. Going with N identical OnStuff wrappers works, technically, but is wasteful.
So my code ends up looking like this instead:
local buttons = BlahBlahContainer.buttons
local b1 = buttons and buttons
if b1 then
local new_1, new_2, ..... = b1:GetScript("OnStuff1"), b1:GetScript("OnStuff2"), .....
for _,b in ipairs(buttons) do
else container hasn't been instantiated yet, respond accordingly
The idea is to use :HookScript to create the wrapper closures for as many On* handlers as you need, and then use :SetScript to point to them directly. This results in N buttons all pointing to one handler function per On* instead of N copies of them.
Strictly speaking, the first iteration of the loop should skip buttons for maximal speed, since that :SetScript is replacing the function pointers with itself and is thus a no-op. Tossup between code clarity versus speeding up a one-time loop (and in a language with no 'continue' statement).
Addon authors interested in checking the veracity of any of the above are invited to insert calls to print(foo:GetScript"OnStuff") as appropriate. :-)