title: How does the __call metamethod in Lua 5.1 actually work?
body: <p>I'm trying, as an exercise, to make a set implementation in Lua.  Specifically I want to take the simplistic set implementation of Pil2 11.5 and grow it up to include the ability to insert values, delete values, etc.</p>
  
  <p>Now the obvious way to do this (and the way that works) is this:</p>
  
  <pre><code>Set = {}
  function Set.new(l)
      local s = {}
      for _, v in ipairs(l) do
          s[v] = true
      end
      return s
  end
  function Set.insert(s, v)
      s[v] = true
  end
  
  ts = Set.new {1,2,3,4,5}
  Set.insert(ts, 5)
  Set.insert(ts, 6)
  
  for k in pairs(ts) do
      print(k)
  end
  </code></pre>
  
  <p>As expected I get the numbers 1 through 6 printed out.  But those calls to <code>Set.insert(s, value)</code> are really rather ugly.  I'd much rather be able to call something like <code>ts:insert(value)</code>.</p>
  
  <p>My first attempt at a solution to this looked like this:</p>
  
  <pre><code>Set = {}
  function Set.new(l)
      local s = {
          insert = function(t, v)
              t[v] = true
          end
      }
      for _, v in ipairs(l) do
          s[v] = true
      end
      return s
  end
  
  ts = Set.new {1,2,3,4,5}
  ts:insert(5)
  ts:insert(6)
  
  for k in pairs(ts) do
      print(k)
  end
  </code></pre>
  
  <p>This works mostly fine until you see what comes out of it:</p>
  
  <pre><code>1
  2
  3
  4
  5
  6
  insert
  </code></pre>
  
  <p>Very obviously the insert function, which is a member of the set table, is being displayed.  Not only is this even uglier than the original <code>Set.insert(s, v)</code> problem, it's also prone to some serious trouble (like what happens if "insert" is a valid key someone is trying to enter?).  It's time to hit the books again.  What happens if I try this instead?:</p>
  
  <pre><code>Set = {}
  function Set.new(l)
      local s = {}
      setmetatable(s, {__call = Set.call})
      for _, v in ipairs(l) do
          s[v] = true
      end
      return s
  end
  function Set.call(f)
      return Set[f]
  end
  function Set.insert(t, v)
      t[v] = true
  end
  
  ts = Set.new {1,2,3,4,5}
  ts:insert(5)
  ts:insert(6)
  
  for k in pairs(ts) do
      print(k)
  end
  </code></pre>
  
  <p>Now the way I'm reading this code is:</p>
  
  <ul>
  <li>When I call <code>ts:insert(5)</code>, the fact that <code>insert</code> doesn't exist to be called means that the <code>ts</code> metatable is going to be searched for <code>"__call"</code>.</li>
  <li>The <code>ts</code> metatable's <code>"__call"</code> key returns <code>Set.call</code>.</li>
  <li>Now <code>Set.call</code> is called with the name <code>insert</code> which causes it to return the <code>Set.insert</code> function.</li>
  <li><code>Set.insert(ts, 5)</code> is called.</li>
  </ul>
  
  <p>What's really happening is this:</p>
  
  <pre><code>lua: xasm.lua:26: attempt to call method 'insert' (a nil value)
  stack traceback:
          xasm.lua:26: in main chunk
          [C]: ?
  </code></pre>
  
  <p>And at this point I'm stumped.  I have absolutely no idea where to go from here.  I hacked around for an hour with varying degrees of increasingly desperate variations on this code but the end result is that I have nothing that works.  What undoubtedly obvious thing am I overlooking at this point?</p>