Default values complaint where there is no default

So what is going on here with this error message in Xojo (2022 4.1):

A ParamArray cannot have a default value
Sub SelectSQL(sqlText As String, Optional ParamArray values() As Variant)

If I wanted a default I’d have to do something like:

Sub SelectSQL(sqlText As String, Optional ParamArray values() As Variant = Nil)

So what is it ACTUALLY whining about? If it would just compile I could figure out what the values() array consists of if not passed in (Nil, empty array?) but instead it’s whimpering about … IDK what. This is the exact documented method signature for SelectSQL() which I am just putting an adapter / proxy out in front of the actual call.

The first error listed at Errors — Xojo documentation

I think a ParamArray is optional by default - it will be an empty array if no parameters are passed.

Hm. And yet here:

It gives this example:

SelectSQL(query As String, Optional ParamArray values() As Variant) As RowSet

Oh well. I guess I’ll just take ParamArray off it and deal with that or … something.

I suppose it’s documented that way because the syntax provided works internally somehow like a ParamArray but actually isn’t.

I’ll try two overloads, one with one argument, one with non-optional ParamArray

ETA: The help popup below the code editor in the IDE shows it just that way, as two overrides, the one with the ParamArray is not shown as Optional. So … another documentation error apparently.

So now I have these methods defined:

ExecuteSQL(sqlText As String)
ExecuteSQL(sqlText As String, values() As Variant)
Select SQL(sqlText As String) As RowSet
Select SQL(sqlText As String, values() As Variant) As RowSet

The first 2 are subs and all calls thereto compile just fine.

The 2nd 2 are funcs and all calls thereto, the compiler says it expects a RowSet but gets an Int32. It also gets confused about interpreting the args to those function calls but that should be a knock-on problem that will go away if I can figure out what it’s on about now.

My first cut quick test implementation for the last override is:

If TargetWindows Then
  Return SqlServerDB.SelectSQL(sqlText,values)
ElseIf TargetMacOS Then
  Return PostgresDB.SelectSQL(sqlText,values)
End If

… so it’s definitely returning a RowSet and that’s the defined return type.

Values isnt defined as a paramarry

FWIW when you DO DEFINE a paramarry use

Select SQL(sqlText As String, paramarray values As Variant) As RowSet

NO () following values as its NOT needed - whoever originally wrote it with () was really really wrong

In the code you write values IS an array of variants that may have 0 or more values in it

You can actually get away with ONE overload and call it as

return selectsql( query )
return selectsql(query, value, value, value)

NOTE THIS WONT WORK quite the same
return selectsql(query, values() )
as you get a paramarray that contains one element - that IS an array

its messy

Just another documentation error. The Optional keyword shouldn’t be there.

What I was getting at is that a ParamArray is optional by default - you won’t get an error if you don’t pass any parameters for the ParamArray, in which case in your method you will get an empty array.

In your original method, just remove the Optional keyword.

So just went into hack mode and instead of two overloads I just went with 2 different-named methods, which resulted in renaming about 20 lines of existing code that calls with param values, and it now works. Xojo could not cope with the overloaded functions. With separate names they work correctly.

Yup, that’s just what I did but then it got confused for other reasons.

Thanks for that. I did not try removing those before I got it working in my hacky way mentioned above … may play more with it later. Moving on for now …

Can you elaborate? I don’t have any issues doing this.

a quick test suggests that two overloads like

Public Sub sqlselect(query as string, values() as variant)
End Sub

Public Sub sqlselect(query as string, paramarray values as variant)
      sqlselect(query, values)
End Sub

are properly distinguished by the compiler when called like

sqlselect("foo")    /// calls paramarray version
sqlselect("foo", 1)    /// calls paramarray version
sqlselect("foo", 1, 3.56)    /// calls paramarray version

Dim v() As Variant
v.append 1
v.append 3.56
sqlselect("foo", v)     /// calls variant array version

and the paramarray version can just call the variant array one :slight_smile:

the compiler generally ignores the () after a PARAMARRAY is seen preceding an identifier in the parameter list

it treats

sub ( paramarray bar() as variant)

as if you wrote

sub ( paramarray bar as variant)

and bar IS an array in the called method

gawd forbid they EVER change that and make the () relevant :stuck_out_tongue:

EDIT : its just confusing for examples to include an irrelevant bit of syntax thats not needed

But, at least in 2021R1.1, if you don’t include the () then autocomplete doesn’t treat it like an array.

On the Xojo forum, I found a number of people complaining that with an overloaded method definition, they will get an error complaining that “there are X definitions for [MethodName] but nothing matching the provided arguments” or words to that effect, even when the call DOES match – followed by “expected [typename] but got Int32”. Which is what I was getting. The resolution appears to always be that there was some kind of name collision in a large project – something in unrelated code accidentally given the same name. I don’t think that’s happening here, but I can’t help but wonder if implementing namespaces in Xojo wouldn’t be a great idea, lol. It is an absent feature that would make me leery of doing a very large / serious project using Xojo.

Thats a bug in autocomplete and the () is a hack to get int to recognize the array
I bet I even know where the source of that error IS
And quite possibly how to fix it:P

The 2019r1.1 built in help docs have it right

And the examples AddNums is definitely right
And written incorrectly in the current version

modules are Xojo’s way of namespacing

and if you define classes in side a module you can use their fully qualified name as the data type in a declaration

there are times that if you do this its required even though it shouldnt be but … compiler guy ?

1 Like