Const AutoEol As Boolean = True
Const LF As String = &u10
Var StrLForNotEnded As String = If(AutoEol, LF, "")
Var StrSysOrNotEnded As String = If(AutoEol, EndOfLine, "")
Itâs the analyzer, not the compiler
Could it be the compiler was expecting EndOfLine.some _value ?
You can invoke the linter with ^K or the compiler with ^B. Same mess.
Nope.
âExpected class EndOfLine, but got TextLiteralâ
EndOfLine in Xojo translates to the equivalent TextLiteral for the current system, and thatâs a valid value. The funny error is âI expected an error, but found a valid value, so Iâll consider it an errorâ
In case of someone wanting a simple workaround:
Const AutoEol As Boolean = True
Const LF As String = &u10
Var StrLForNotEnded As String = If(AutoEol, LF, "")
Var StrSysOrNotEnded As String = If(AutoEol, EndOfLine+"", "")
The documentation reads:
result = EndOfLine
or
result = EndOfLine.EndOfLineType
Part Type Description result String The end of line String specified by EndOfLineType. EndofLineType String The end of line String being requested. The choices are:
- Windows
- Unix
- macOS|
Can it be that EndOfLine by itself does not return a string ? If so, that is a bug !
What happens if you type EndOfLine.MacOS ?
Again, everybody uses this for ages. EndOfLine by itself is the literal string equivalent EOL for the current system, as stated in your print of the manual above. The compiler itself calls it âTextLiteralâ in the âErrorâ. Then when I add a empty string to the value, doing nothing, it works as it should.
It will return what you asked for, but not what I asked for.
So in this case the compiler does not complain. Looks like a bug.
I understand, but that does not prevent a developer, or even Apple, from breaking the codeâŠ
Out of curiosity, what are the OS and Xojo versions ?
The compiler doesnât do the operator convert or whatever magic is needed to covert EndOfLine to text. The problem is the second argument and third argument of your if(condition, a, b)
are different types and the in-line if requires them to be the same type.
seems EndOfLine does not return a string as the manual said.
Var s As String = If(True,CType(EndOfLine,String),"")
The destination, the left side of the attribution, is String, all the operands of an âinlineâ (not function) IF are strings, in case of any of those contents having some type of type selection, instead of fixed one, the selection to be tried is the destination one, the attribution, and that means, a String in this case.
The âinlineâ IF is not working as a real inline IF, because if
Var StrSysOrNotEnded As String = EndOfLine
Works; an inline
Var StrSysOrNotEnded As String = If (True, EndOfLine, "")
Should too.
Actually @Jason_King is right, lets clear that out.
Actually EndOfLine is an Object that returns a string, NOT a âliteral stringâ.
When you send a OBJECT and a string to the If operator, you get exactly the behavior documented: âHaving no common type results in a Type Mismatch compile error.â
Kind of weird redaction but is documented, different types, you get the error.
And this is the problem, you are not understanding what the compiler is telling you.
Lets translate the âExpected class EndOfLine, but got TextLiteralâ to a more verbose thing the compiler may say: "I got a string in the second parameter but I was expecting a Object of type EndOfLine in there BECAUSE you put a Object of type EndOfLine in the first parameter and both should be the same type.
In other words, the compiler first evaluates if the two passed values are of the same type (doesnt care if the object will return a string), if they are not the same type, you get the Type Mismatch error.
Of course, Xojo could change the IF behavior internally to first evaluate the expresions pased and THEN evaluate if the results of both expressions are the same type. But, that is another thing.
In this case, the + Operator forces the compiler to first evaluate the EndOfLine object to make the concatenation and then the result string is passed, so, both values passed are the same type.
An inline function would be forced to evaluate to the target type, itâs not the same as a function and parameter types, I know that I forced it as if it was one , because I perceived the weird way Xojo behaved, the worse of 2 worlds.
As an Inline it should render as intended, as a function the same, but it gets confused and ends needing a conversion tip.
The other way to render as expected would be having a function with the expected signatures, so Xojo didnât get confuse on how to solve the target type, like:
Public Function IIF(first As Boolean, s1 As String, s2 As String) As String
If fisrt then
Return s1
Else
Return s2
End
End Function
Var StrSysOrNotEnded As String = IIf(true, EndOfLine, "") // works
Ivan explained how to read and understand the error message. Anyway, this is compiler-, sorry, analyzer-stupidity; we have a statement of type string, so the result of the expression has to be of type string. Therefore all types are known and IMHO thereâs nothing wrong to expect that this works.
In line if
does not do type coercion. It is an operator, not a function. If you call a function the type is coerced for you. See the notes section: https://documentation.xojo.com/api/code_execution/if.html
I suspect that if you flipped the order so the string is first it may âworkâ like you expect since then it is clear that the EndOfLine OBJECT has to be converted to the common type with operator convert. But the compiler canât make that assumption since the first value of the operator is an object not a string literal.
Then you just need an infinite number of functions to acomodate all posible combinations of objects passed
OR you can use a single function using variants:
Public Function IIF(first As Boolean, v1 As Variant, v2 As Variant) As Variant
'if you use a variant, v1 will be a EndOfLine object in here, not a String
End Function
If you use variants, the compiler CANNOT determine the type of the value at compile time. So you will end with the OBJECT passed, it is a little more trickier than it looks like at a first glance.
Anyway, the function behaves as documented and the error message is correct. Just use it as intended.
Xojo is not smart enough to take some smart considerations, it many times does simple considerations like this one (and sometimes reports confusing messages due to its rules). In the past I discussed about some features with Joe, the last âcompiler architectâ about how Xojo solved some expressions, I donât remember anymore, maybe it was something about Xojo getting wrong values due to not promoting some values to the proper superior scales to accommodate larger intermediate values. I do remember it solved different things in the same fixed way, 32 bit, even when we needed 64 resolutions, disregarding the target, it just truncated the value and done, this kind of thing.
Or just change the behavior to something like real a ternary operator, where a x = if(bool, y, z) wants y and z to solve to a compatible type x.
But no need to argue anymore. The case ended posts and posts above. And the current Xojo behavior is annotated in the manual.
EndOfLine
apart of how xojo behave.
you could make a (unhopeful) feature request with EndOfLine.Automatic
because EndOfLine.Windows in IF(,) works.