Может ли Lua поддерживать вызовы методов без учета регистра? - PullRequest
4 голосов
/ 02 февраля 2012

Я использую Lua в качестве языка описания данных для моего приложения C ++. У меня есть куча классов C ++, связанных с Lua с использованием SLB 2.0. У меня есть связанные методы, такие как «SetPos» или «SetName». Я указываю позицию или имя (например), используя таблицу со значениями, обозначенными как «pos» или «name». Я хочу иметь возможность взять ключ, добавить preset и вызвать метод, если он существует (может и не быть). Это возможно? Если да, то есть предложения?

Я знаю, что мог бы сделать свои связанные методы строчными, но я бы предпочел оставить их такими же, как методы, к которым они привязаны (хотя это может быть мой запасной вариант). Я мог бы попытаться построить имя метода на основе моих стандартов именования, но нечувствительность к регистру менее подвержена ошибкам.

Я чувствую, что должен быть хитрым куском Lua, который мог бы решить эту проблему с помощью метатаблиц, но я сам не смог решить это.

Есть предложения?

Спасибо!

1 Ответ

6 голосов
/ 02 февраля 2012

Нечувствительность к регистру на самом деле не то, что Луа обрабатывает.Все обращения к таблицам и доступ к локальным переменным, в конечном счете, сравниваются с учетом регистра.

Лучшим решением было бы просто признать, что вы имеете дело с чувствительной к регистру системой, такой как C ++, и справиться с ней.

Однако, если вы действительно хотите, вы можете сделать это.Простейшим способом было бы поместить все возможные варианты перестановки имени в вашу таблицу функций.Таким образом, ваша таблица функций будет иметь следующее значение:

["setname"] = theFunction,
["Setname"] = theFunction,
["sEtname"] = theFunction,
["SEtname"] = theFunction,
...

Конечно, вы можете автоматизировать это с помощью функции, которая берет каждое имя в таблице и реплицирует его данные на основе перестановок регистра.

Aболее сложным, но более простым в использовании механизмом будет использование метаметодов __index и __newindex вместе с трюком с пустой таблицей.

function CreateCaseInsensitiveTable()
  local metatbl = {}

  function metatbl.__index(table, key)
    if(type(key) == "string") then
      key = key:lower()
    end

    return rawget(table, key)
  end

  function metatbl.__newindex(table, key, value)
    if(type(key) == "string") then
      key = key:lower()
    end

    rawset(table, key, value)
  end

  local ret = {}
  setmetatable(ret, metatbl)
  return ret
end

Вместо создания таблицы с {}, вы создаете таблицу сэтот вызов функции.В противном случае таблица должна функционировать как обычно (хотя очевидно, что доступ к элементу будет немного медленнее).

...