I was going through some old code and discovered a change in behavior. Previously (version 0.2.3 and earlier?), if you did sub(str,1,nil)
, you would get the full string. Now, you only get the first letter of that string. I believe the recent API update for optimization is incorrectly evaluating nil args as 0, both for start and end.
This behavior was useful if you wanted to have a table of string lengths for tokenized text display, as in ?sub(dialog,1,dialog_token[time])
. Once the time var had reached above the size of the dialog_token table, the default table nils had the same behavior as showing the full string. I can fix with a min(#dialog_token,...), so not crucial, but the old behavior feels more intuitive to me.
This was an intentional change, though I agree it's wonky:
Added: sub(str, pos, _) to get a single character at position pos
(Here, _ is used as a variable that generally contains nil (it will if you don't assign/declare it))
That is... an unfortunate change. To be honest, sub usage is actually one of the least intuitive aspects of Lua/Pico-8, and this only makes it more complicated (as sub(str,pos)
unintuitively returns from pos to the end of the string, which is especially confusing in the context of this new feature).
If we're talking API changes, why not add str[ix] indexing via metatables by default? getmetatable('') currently returns nil, so setting the __index function isn't even doable inside of pico-8, and would have to be patched in the core engine code. I think that would be a much better way to add this functionality, and would preserve sub as a specialty function for slices of text only.
Yep, @shy and @thisismypassword.
The easiest solution for this is:
str="apple" pos=2 cls() print(sub(str,pos,-1)) |
Always have -1 on the end for a 3rd argument and you should get the desired behavior of truncating first characters but not the last.
As mentioned at the top, I'm using table abuse to get nils when out of bounds. I can easily fix this indexing via t[ix]or-1
or similar, but I think it's more intuitive if sub(s,i,nil)
and sub(s,i)
do the same thing, especially since the second one cannot be changed due to backwards compatibility.
I think it might have been better to choose a different "special value" like true
.
It's not too late, a breaking change sucks but a bad legacy choice is worse.
PS: In my opinion, the whole "use _
for nil
" idea is a bad programming pattern in the first place. Assuming the variable _
will always be unassigned is asking for trouble when we also do stuff like for _,v in pairs(tbl)
. You can treat _
as nil
or as a dummy var, but you can't do both safely.
[Please log in to post a comment]