5

I am trying to build a CNN using Torch 7. I am very new to Lua. I was trying to follow this link. I encountered something called setmetatable in the following code block:

setmetatable(train_set, 
{
  __index = function(t, i) 
    return {t.data[i], t.label[i]}
  end
});

I understand that the second argument acts as the metatable for the table train_set.

1) Is t the metatable or is t just another name for train_set?

2) Whenever a function is used against __index, does the interpreter assume the first argument (t) to be a table (or metatable, depending on answer to first question)? And is the second argument always the key or index?

3) My understanding is that if I use train_set.data[1], it will invoke the __index. The answer here says that __index is invoked when key does not exist in the table. But is t.data[1] same as train_set.data[1]? If so, how does the interpreter know that?

Community
  • 1
  • 1
skr
  • 914
  • 3
  • 18
  • 35

2 Answers2

10
setmetatable(train_set, 
{
  __index = function(t, i) 
    return {t.data[i], t.label[i]}
  end
})

Here we have some table named train_set. With this function call we set its metatable to

 {
  __index = function(t, i) 
      return {t.data[i], t.label[i]}
  end
 }

This is an anonymous table. If this is hard to read for you, you could also write:

local my_metatable = {
  __index = function(t, i) 
     return {t.data[i], t.label[i]}
  end
}
setmetatable(train_set, my_metatable)

Inside that metatable we implement the metamethod __index. By doing this we tell Lua what to do when someone is indexing a field in train_set that does not exist.

So when we ask Lua to give us the value stored in train_set[4] for example and train_set[4] is nil, Lua will go check if __index is implemented. If so it will call __index(train_set, 4) and give you its return value or otherwise return nil So the interpreter knows that t.data[1] is the same as train_set.data[1], because he's the one who put train_set into __index.

So when you implement __index it will always be called using the indexed table as first and the index as second argument.

Piglet
  • 27,501
  • 3
  • 20
  • 43
4

First, two important links:

Now the answers:

  1. t, the first parameter of the __index method in a metatable, refers to the table that has the metatable, here train_set. This parameter allows to reuse the same metatable for several tables.

  2. __index is a special function inside metatables (look at the metatable events), that is called whenever a field in the metatabled table is accessed but missing. For instance, if train_set does not contain the key k and you read train_set.k, there will be a call to __index (train_set, "k") in its metatable.

  3. From what i can infer from the code, the usage pattern in your example looks like local x = train_set [1] that will return a table containing { train_set.data[i], train_set.label[i] }.

Alban Linard
  • 1,037
  • 9
  • 19