Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

Error when concatenating strings, help?

Asked by 7 years ago
Edited 7 years ago

I am making a simple display that shows a number value in a TextLabel. For this, I want the label to display unit separators (separators between thousands and millions for example).

I wrote some code for it, using tostring() to get a String from the number, and string:len() to get the necessary length and cut the string accordingly using string:sub().

Just when everything was going well, by testing the display and entering a 4-digit number (e.g. 1337), the output window gave me an error ('attempt to concatenate a nil value'). I tried fixing it but still can't come up with a solution.

[Code]

local vl = (tostring(v.Value)):len()
local function vv(spos, epos)
    if spos > 0 then
        tostring(v.Value):sub(spos, vl + epos)
    elseif spos < 0 then
        tostring(v.Value):sub(vl + spos, vl + epos)
    end
    return
end
if vl < 4 then
    va.Text = v.Value .. "  "
elseif vl >= 4 and vl < 7 then
    va.Text = vv(1, -3) .. "." .. vv(-2, 0) .. "  "
elseif vl >= 7 and vl < 10 then
    va.Text = vv(1, -6) .. "." .. vv(-5, -3) .. "." .. vv(-2, 0) .. "  "
end

-- v is correctly defined to my IntConstrainedValue
-- va is correctly defined to the TextLabel display

Any help will be appreciated!

:3

EDIT: Solved! Thank you. I changed my earlier code to this (which also is shorter in case you want it too)

local vs = tostring(v.Value)
if #vs < 4 then
    va.Text = v.Value
elseif #vs < 7 then
    va.Text = vs:sub(1, #vs-3) .. "." .. vs:sub(#vs-2)
elseif #vs < 10 then
    va.Text = vs:sub(1, #vs-6) .. "." .. vs:sub(#vs-5, #vs-3) .. "." .. vs:sub(#vs-2)
else
    print("Can't handle '" .. vs .. "' (" .. #vs .. ")")
end
va.Text = va.Text .. "  "

1 answer

Log in to vote
1
Answered by
BlueTaslem 18071 Moderation Voter Administrator Community Moderator Super Administrator
7 years ago

First, a tip: use the # operator instead of :len() to greatly shorten up your code. It would mean you could say

local v = tostring(v.Value)

and you just use #v instead of vl everywhere.


The problem is that vv can return nothing (which is nil) on line 8 (if you meant that that line shouldn't have been reached, you should have error("unreachable") or assert(false))

I'm not really sure what the purpose of vv is because a regular old :sub would probably work fine:

if #v < 4 then
    va.Text = v

-- "else" means "not previous condition" -- you don't need to say v >= 4
elseif #v < 7 then
    va.Text = v:sub(1, -4) .. "." .. v:sub(-3, -1)
elseif #v < 10 then
    va.Text = v:sub(1, -7) .. "." .. v:sub(-6, -4) .. "." .. v:sub(-3, -1)
else
    error("I don't know how to handle numbers as big as " .. v)
end
0
The function is there to avoid writing long repeating lines between the parenthesis, to shorten code... I'll have to check if it really does shorten it though TheArmoredReaper 173 — 7y
0
by using something that's similar but subtly (buggy) different from v:sub, and only 2 characters shorter, I don't think you save anything BlueTaslem 18071 — 7y
0
It worked! I rewrote the whole part using your suggestion and it worked just fine! Thank you! TheArmoredReaper 173 — 7y
Ad

Answer this question