Somehow there seems to be a difference, when passing a string in via a variable vs. passing a string via an expression as an argument.
I am so confused right now, about how Lua evaluates expressions.
In short: I am trying to detect a word, case insensitive and I am reformatting the pattern, so it is not case sensitive. If I pass the argument directly to <string>:match
(sidenote: issue persists with directly calling string.match
), it doesn't give the expected behaviour, while it does, when passing it via a local variable.
I have destilled the code into a reproducable script (Windows: Lua 5.4.3
and Lua JIT 2.1.0-beta3
, WSL: Lua 5.3.3
, Linux: Lua 5.1
):
-- Replaces each char with a charset pattern in uppercase and lowercase
local function makeCaseInsensitive(name)
return name:gsub("%a", function (c)
return string.format("[%s%s]", c:lower(), c:upper())
end)
end
local suite = "Retained widgets"
local pattern = "retained"
if suite:match(makeCaseInsensitive(pattern)) then
print("In expression ok")
else
print("In expression not ok")
end
local insensitive = makeCaseInsensitive(pattern)
if suite:match(insensitive) then
print("In variable ok")
else
print("In variable not ok")
end
The expected output would be:
In expression ok
In variable ok
instead:
In expression not ok
In variable ok
WTF is going on? Could someone please explain to me, what is going on?
Any feedback is appreciated
As @MikeV. pointed out in the comments: makeCaseInsensitive(pattern)
returns two arguments. This is due to string.gsub
returning the replacement and the replaced character count: 8
.
The solution is to discard the rest from gsub
, either explicitly:
-- Replaces each char with a charset pattern in uppercase and lowercase
local function makeCaseInsensitive(name)
local caseInsensitivePattern, count = name:gsub("%a", function (c)
return string.format("[%s%s]", c:lower(), c:upper())
end)
return caseInsensitivePattern
end
or implicitly by adding extra parenthesis:
-- Replaces each char with a charset pattern in uppercase and lowercase
local function makeCaseInsensitive(name)
return (name:gsub("%a", function (c)
return string.format("[%s%s]", c:lower(), c:upper())
end))
end