2013-11-22 2 views
4

Я узнавал о метатаблицах в Lua, и я хотел бы реализовать операторы дальности, как и в Ruby, так что я использовал эту модельLua пользовательского номер конкатенация

debug.setmetatable(1, { 
    __concat = function(a, b) 
     if a > b then 
      error(table.concat({ 
       "attempt to create a range of values with a", 
       "minimum larger than the maximum" 
      }, " ")) 
     elseif a == b then 
      return a 
     else 
      return unpack((function(nStart,nEnd) 
       local nTable = {} 
       for it = nStart,nEnd do 
        table.insert(nTable, it) 
       end 
       return nTable 
      end)(a, b)) 
     end 
    end 
}) 

print(6 .. 6) 

Но, кажется, что он продолжает использовать поведение по умолчанию , Есть ли способ заставить это работать? Я знаю, что я мог бы создать функцию для эмуляции поведения и называть его диапазоном (n, n2) или аналогичным, но это побеждает цель. Благодарю.

ответ

4

См. section 3.4.5 руководства Lua 5.2.

Оператор конкатенации строк в Lua обозначается двумя точками ('..'). Если оба операнда являются строками или числами, то они преобразуются в строки в соответствии с правилами, указанными в п. 3.4. В противном случае вызывается метамод __concat (см. П. 2.4).

Если вы хотите изменить это поведение, ознакомьтесь с lvm.c, в частности функцией luaV_concat.

+0

Спасибо, я не думаю, что могу легко изменить это поведение? – Hal

+1

Вам нужно будет найти основную работу в генераторе кода, которая устраивает эффект 'tostring()' рядом с конкатенацией. Источники Lua довольно хорошо комментируются, но это не будет тривиально. Первым шагом было бы исключить автоматическое преобразование в строку, второе - расширить использование '__concat'. – RBerteig

+1

@Hal Это выполнимо, но вам нужно знать, по крайней мере, C. Пожалуйста, см. Добавление к моему ответу. Это может быть больше усилий, чем его ценность, хотя вы можете сделать простую функцию «range». Синтаксический сахар имеет свои затраты. –

Смежные вопросы