Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the boolean interpolation character for string.format function in lua

I'm looking for a boolean interpolation character for string.format(as the title says).
I want something that will work this way:

print(string.format("nil == false: %b",(nil==false))

%b is just a placeholder, you'll get an error with that. I'm looking for 'b'. I can't just do:

print("nil == false: " .. (nil==false))

because booleans can't be concatenated with strings. I could do:

val=(nil==false)
if val==false then truth="false" else truth="true" end
print("nil==false: ".. truth)

But it's too much work.

like image 885
Plakhoy Avatar asked Oct 31 '25 01:10

Plakhoy


2 Answers

Well, first you should try reading the relevant section of the manual. That will let you discover that there is no format specifier for booleans.

What greatwolf suggests is a solution, i.e. converting the value explicitly to a string. If there is a possibility that your truth value may be nil, but you want to output it as false, this trick is useful:

truth = nil
print("nil==false: ".. tostring( not not truth ))

In this way both nil and false will be displayed as false.

Edit (to answer a comment)

In Lua 5.2 the %s specifier automatically convert the arguments to strings using tostring internally. Thus:

print( string.format( "%s  %s  %s", true, nil, {} ) )

prints:

true  nil  table: 00462400

otherwise you can create your own formatting function wrapping string.format:

 local function myformat( fmt, ... )
    local buf = {}
     for i = 1, select( '#', ... ) do
         local a = select( i, ... )
         if type( a ) ~= 'string' and type( a ) ~= 'number' then
             a = tostring( a )
         end
         buf[i] = a
     end
     return string.format( fmt, unpack( buf ) )
 end


 print( myformat( "%s  %s  %s", true, nil, {} ) )
like image 194
Lorenzo Donati -- Codidact.com Avatar answered Nov 02 '25 23:11

Lorenzo Donati -- Codidact.com


If you're wondering how to modify string.format so it supports bools, here's one way you can do it:

do
local format = string.format
function string.format(str, ...)
  local args = {...}
  local boolargs = {}
  str = str:gsub("%%b", "%%%%b")
  for i = #args, 1, -1 do
    if type(args[i]) == "boolean" then
      table.insert(boolargs, 1, args[i])
      table.remove(args, i)
    end
  end
  str = format(str, unpack(args))

  local j = 0
  return (str:gsub("%%b", function(spec) j = j + 1; return tostring(boolargs[j]) end))
end
end

print(string.format("%s is %b", "nil == false", nil==false))

It might be a bit confusing to follow. The idea is to gsub all "%b" in the string and replace it with double escape %%b so format doesn't try to interpret it. We let string.format do its stuff and we take the result and handle %b manually ourselves.

like image 20
greatwolf Avatar answered Nov 03 '25 01:11

greatwolf



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!