Я пишу диссектор Wireshark на Lua для пользовательского типа пакета, а версии Wireshark, включая Lua 5.2 и ниже (текущие версии выпуска), включают библиотеку BitOp, тогда как предстоящие выпуски будут иметь Lua 5.3 или более позднюю версию и будут использовать встроенные побитовые операции.
Моя цель состоит в том, чтобы это изменение автоматически обрабатывалось версией Lua без необходимости обновлять диссектор для каждой версии. Мой текущий код:
local bit = nil
if tonumber(string.sub(_VERSION, 5)) < 5.3 then
bit = require("bit")
end
local version_byte = 0xaf
if bit then
print("BitOp method")
else
print((version_byte >> 4) * 10 + (version_byte & 0xf))
end
Проблема в том, что Lua 5.2 (конечно) не распознает операторы побитового сдвига и & и выбрасывает unexpected symbol near '>'
. Есть ли способ условно оценить что-то подобное?
К вашему сведению, Wireshark по-прежнему будет поддерживать библиотеку Lua BitOp даже в Lua 5.3 и 5.4. Цитируем примечания к предстоящему выпуску: «Включенная версия Lua была обновлена до 5.4. Хотя большинство диссекторов Lua должны продолжать работать (библиотека lua_bitop была исправлена для работы с Lua 5.3 и 5.4, в дополнение к нативному Lua поддержка битовых операций, присутствующих в этих версиях), совместимость различных версий Lua не гарантируется.».
Это условная компиляция. Конечно вы можете.
if bit then
print("BitOp method")
else
load[[
-- arbitrary chunk of code
print((version_byte >> 4) * 10 + (version_byte & 0xf))
]]()
end
Однако это вызовет проблемы с доступом к местным жителям (например, local version_byte
). Поэтому вам придется соответствующим образом переписать свой код.
Потрясающий ответ, спасибо! Принял.
Вы могли бы написать пару модулей прокладки совместимости, которые определяют общий интерфейс для битовых операций: один, который определяет функции, выполняющие битовые операции в Lua до 5.3, и другой, который определяет функции для 5.3 и более поздних версий, которые используют встроенные операторы под капот:
-- bit_shim_5_2.lua
-- Defines a common interface to bit operations.
local M = {}
function M.bitop ()
print("Lua pre-5.3 bit ops")
end
return M
-- bit_shim_5_3.lua
-- Defines a common interface to bit operations.
local M = {}
function M.bitop ()
print("built-in Lua 5.3 bit ops")
end
return M
-- main.lua
local bit = nil
local version = tonumber(string.sub(_VERSION, 5))
if version < 5.3 then
bit = require("bit_shim_5_2")
else
bit = require("bit_shim_5_3")
end
bit.bitop()
Запуск этой программы на Lua 5.4.7 дает:
$ lua main.lua
built-in Lua 5.3 bit ops
Это потрясающий ответ и хорошее решение. Я думаю, для простоты я просто буду использовать load()
, но модульное решение определенно может быть ответом на чьи-то потребности. Для Wireshark проще не иметь дело с модулями в папке диссектора Lua, но это очень чистое решение для других ситуаций.
@AndrewYim Похоже, что из-за ошибки при компиляции она даже не позволяет достичь части pcall. Я протестировал его, и результат не изменился, все еще не удалось скомпилировать «неизвестный» оператор.