When a Parameter is an Optional ParamArray can you pass array?

Documentation includes this

TrimLeft (Optional ParamArray characters() As String) As String

So if you want to chop off the characters a b c of the left side of a string

Var someString As String = "afrog"
Var trimOffLeft As String
trimOffLeft = someString.TrimLeft("a", "b", "c")

You successfully get rid of the “a” on the left side of “afrog”.

Now let’s say that you want to determine which characters are to be trimmed at runtime.

You might hope this would work

Var rid() As String = Array ("a", "b", "c")
trimOffLeft = someString.TrimLeft(rid)

But that is not allowed.

Is there any trick that lets you determine, in the program, the contents of the Optional ParamArray that going to be being passed to TrimLeft, or is that impossible?

An Array is not a ParamArray, that said, you should ask Xojo for an overloaded version as

TrimLeft (characters() As String) As String

1 Like

Meanwhile you could implement something like this in a module:


Public Function TrimLeft(extends s As String, characters() As String) As String

  Var sizeBefore As Integer

  Do

    sizeBefore = s.Length

    For each char As String in characters

      s = s.TrimLeft(char)

    Next

  Loop Until sizeBefore = s.Length // removed all chars in the array

  Return s

End Function

// ---------------------------------------------

Var x As String = "abaacccbaXYZ"

x = x.TrimLeft(Array("a","b","c")) // x = XYZ
1 Like

I appreciate the explicit explanation that my hope for somehow “passing” a parameter array was not a way forward.

Use cases until now probably were well defined at design time, and using a small list of “chars”, so a hardcoded inline list as ParamArray offers should solve such necessity. If you have some special use case for dynamic list, I guess my method will help you and unlock your development. If you imagine more people will need it, a feature request should be made and such feature included in Xojo Standard library.

Just to be clear, if you think you want both behaviors, a paramarray and a regular array, you could create both signatures and have the first call the second so there’s just one implementation.

As I see it, the current issue is the other way around: when one has some parameters to pass (whose count is undefined at compile time) to methods which accept ParamArray, it would be nice to “automatically” be allowed to pass an array, so you can pass an arbitrary-sized list of parameters.

4 Likes

IIRC correctly, when Param Array was first introduced it worked that way but was quickly changed… Don’t recall if it made it into a release or only in a beta way back when.

That said, overloading does take care of that when you want it.

-Karen

Yes, if the compiler could accept a ParamArray chars() as String and a chars() As String transparently, this kind of problem would be nonexistent.

1 Like

So the problem with that is that you wouldn’t know inside the method whether the array was the original array or not. Remember Arrays are objects so if you were to remove the last item from the array when called like this, you’d get two different results:

Dim arr() as String = array(1,2,3,4)

MyMethod(arr)

// arr = (1,2,3)

But calling it this way:

MyMethod(1,2,3,4)

There’s no original array to manipulate. Talk about a potential bug that’s very hard to track down.

How? The system creates a copy? What about giving immutable powers to the compiler, so if someone tries to set a value to an immutable the compiler complains?

Like a signature like:

TrimLeft (Optional ParamArray characters() As String) As String
TrimLeft (ReadOnly characters() As String) As String

You first tip ignored your second advice.

1 Like

No, it doesn’t. When you pass an array to a method, it’s a reference because arrays are objects.

^ Again, this example is a ParamArray, not an Array, so I guess it internally composes a temporary array, a copy of such hardcoded parameters, that instead of being immutables due to be hardcoded literals, constants and not variables, they can be changed, as they are substituted by a temporary variable, but as a disposable copy, would not cause side effects.

And… a PoC:

Immutables like

TrimLeft (ReadOnly characters() As String) As String

Would be handy for such cases.

Good point. (but…)

For this, an exception could be raised, which would make the issue obvious.

But it’s not an error. Whether or not you pass an array byref is dependent on the form you use…

Sub MyMethod(arr() as string) // Array is passed (ByRef)
Sub MyMethod(paramArray arr as string) // Array is Created (ByVal)

There’s no error to catch at runtime because there’s nothing going wrong.

What I’m saying is that if Xojo were to automagically generate a separate matching method whenever you created one of these, the behavior between them would be different and very hard to explain.

Now, what Xojo could do here is give you a way in the IDE to create the other method, possibly by right-clicking the method in the navigator. But it’s not going to always be available. Paramarrays can only be placed at the end of a parameter list, whereas an array can be anywhere.

Here, no. But I was referring to raising an exception when one tries to modify an array that has been passed as ParamArray (not passing the array itself).

But there’s nothing wrong with that either. The array was created for you, just like any other ByVal parameter. Strings, Integers, Doubles, unless you specify ByRef, a new instance of the variable is created inside the method and you can change it as needed. Having paramarray behave differently would just be confusing, not to mention potentially breaking lots of code if a behavior change were made.