Это работает ...
if ( tileType == "water" or
( otherObj and otherObj:GetType() == "IceBlock" )) then
self:SetNoClip( true )
else
self:SetNoClip( false )
end
-
Это не ...
self:SetNoClip( tileType == "water" or
( otherObj and otherObj:GetType() == "IceBlock" ))
//----------------------------------------------------------
local noClip = ( tileType == "water" or
( otherObj and otherObj:GetType == "IceBlock" ))
self:SetNoClip( noClip )
Тест otherObj
просто оценивает, является ли otherObj nil
или нет. Указанные переменные извлекаются в предыдущей строке. Ошибка, которую я получаю при запуске приложения:
unprotected error to call in Lua API(script path...: Did not pass boolean to SetNoClip).
SetNoClip - это функция в приложении, которая захватывает аргумент, помещаемый в стек lua через lua_toboolean
.
Так почему же работает первая, вторая и третья ошибки?
EDIT:
SetNoClip имеет это определение.
int GameObject::LuaSetNoClip( lua_State *L ) {
if ( !lua_isboolean( L, -1 )) {
LogLuaErr( "Did not pass boolean to SetNoClip for GameObject: " + m_type );
return luaL_error( L, "Did not pass boolean to SetNoClip" );
}
m_noClip = lua_toboolean( L, -1 );
return 0;
}
Проблема в том, что lua_isboolean
не выполняет никаких неявных преобразований типов (но lua_toboolean
делает) и будет возвращать true только для литеральных логических значений. Поэтому, если он увидит ноль, он вернет, что логическое значение не было передано. Я только что удалил проверку ошибок для логического литерала, поскольку люди (включая меня) обычно полагаются на аргументы, которые не являются логическими литералами и обрабатываются правильно как логические.