title: implementing torch's __len__ meta function
body: <p>In our <a href="https://github.com/AlexMili/torch-dataframe" rel="nofollow">torch-dataframe</a> project we're trying to implement <code>__len__</code> meta function as follows :</p>
  
  <pre><code>MyClass.__len__ = argcheck{
      {name="self", type="MyClass"},
      {name="other", type="MyClass"},
      call=function(self, other)
      return self.n_rows
  end}
  </code></pre>
  
  <p>This works in Lua 5.2 and 5.3 but for Lua 5.1, luajit 2.0 and 2.1 the returned variable is not the actual row number but 0. The sense is that it returns a new instance of MyClass but it's hard to understand why. There is a note about __len changing <a href="https://www.corsix.org/content/look-lua-52-work3" rel="nofollow">here</a> but that's the best doc hint we've managed to locate so far.</p>
  
  <p>A little surprising is the need for two arguments. When <code>argcheck</code> is provided with a single argument version:</p>
  
  <pre><code>MyClass.__len__ = argcheck{
     {name = "self", type = "MyClass"},
     call=function(self)
     return self.n_rows
  end}
  </code></pre>
  
  <p>it throws:</p>
  
  <pre><code>[string "argcheck"]:28: 
  Arguments:
  
  ({
     self = MyClass  -- 
  })
  
  
  Got: MyClass, MyClass
  </code></pre>
  
  <p>We currently rely on the <code>argcheck</code> overload operator for handling this:</p>
  
  <pre><code>MyClass.__len__ = argcheck{
      {name="self", type="MyClass"},
      {name="other", type="MyClass"},
      call=function(self, other)
      return self.n_rows
  end}
  
  MyClass.__len__ = argcheck{
      overload=MyClass.__len__,
      {name="self", type="MyClass"},
      call=function(self)
      return self.n_rows
  end}
  </code></pre>
  
  <p>For more details here is the full class and the travis report :</p>
  
  <ul>
  <li><a href="https://github.com/AlexMili/torch-dataframe/blob/develop/Extensions/metatable.lua" rel="nofollow">Full metatable class</a></li>
  <li><a href="https://travis-ci.org/AlexMili/torch-dataframe/builds/135456976" rel="nofollow">Travis report</a></li>
  </ul>
  
  <h2>Test case</h2>
  
  <p>Here's a full test-case that works as expected in 5.2 and 5.3 that perhaps illustrates the problem in a more concise way that the full package:</p>
  
  <pre><code>require 'torch'
  local argcheck = require "argcheck"
  
  local MyClass = torch.class("MyClass")
  
  function MyClass:init()
      self.n_rows = 0
  end
  
  MyClass.__len__ = argcheck{
      {name = "self", type = "MyClass"},
      {name = "other", type = "MyClass"},
      call=function(self, other)
      print(self.n_rows)
      print(other.n_rows)
      return(self.n_rows)
  end}
  
  local obj = MyClass.new()
  obj.n_rows = 1
  local n = #obj
  print(n)
  </code></pre>
  
  <p>This prints as expected:</p>
  
  <pre><code>1
  1
  1
  </code></pre>