Can a Class return a value like a function?

I am still getting to know Xojo. One thing I am looking at is eliminating position-dependent parameters for functions, especially when there are a large number of them. For example, instead of entering:

Result = Fn (123, 234, 345, 456, 567)

I would like to enter:

[quote]DIM f AS NEW Fn
f.a = 123
f.b = 234
f.c = 345
f.d = 456
f.e = 567
Result = f[/quote]

A distinct advantage of this method is all parameters can be optional, with default values. With positional dependent parameters, I must enter all optional parameters the precede the one parameter I want to optionally include.

I can almost get there by creating a Class with properties a, b, c, d, e. In the class I add a method - let’s call it Action - that processes the parameters a, b, c, d, e and returns a value. The net effect is:

[quote]DIM f AS NEW Fn
f.a = 123
f.b = 234
f.c = 345
f.d = 456
f.e = 567
Result = f.Action[/quote]

Is there a way to call the method ‘Action’ by default, so the last line of the above code could be:

Result = f

I looked at Class Interface (I have never used one), but I don’t think that is what I need.

Thanks in advance for any suggestions.

I think you’re looking for operator_convert()

Thanks, Jim.

I’m having trouble implementing Operator_Convert. Do you know of any examples I could use as a guide?

This is a bad idea at any rate. Why ?
Every function that can take a variable number of arguments will need to be converted to a class
So instead of a large number of functions with varying argument lists you will have an enormous pile of classes that are nothing more than functions wrapped into a class

IF what you’re trying to achieve is “named parameters” you’d be better off to just pass a dictionary that is key value pairs where the keys are the names of the parameters and the values are the values for that named item

Thanks for the update, Norman. I’ll look into dictionaries. I assume the function uses CASE statements to align the dictionary keys to the parameters.

Also see if ParamArray is a good fit for what you’re trying to do.

you do this manually
there are NO “named parameters” in Xojo - period full stop

there are OPTIONAL ones though

you can define a method in a way that you can supply, positionally, some or all of the parameters


    Function Foo( a as integer = -1, b as integer = -1, c as string = "" )
    End Function

can be called as


Kem - I was not aware of ParamArray. It does not do what I am looking for, but it does solve a different issue I was having.

This is a great forum !!


Norman - I experimented with the Dictionary. It is a little clumsy at first, but I can see the appeal. Best of all, as you already pointed out, the code is not littered with Classes and Properties, as the dynamic dictionaries last only as long as you need them.

I am going to give this a try in my real code.

Thanks for your help.

ParamArray with pairs might left you “fake” named parameters easier

Private Sub Foo(ParamArray values as Pair)
  TextArea1.AppendText CurrentMethodName + " called" + EndOfLine
  For i As Integer = 0 To values.ubound
    TextArea1.AppendText Str(values(i).Left) + " = [ " + Str(values(i).Right) + "]" + EndOfLine
  TextArea1.AppendText "==========================================" + EndOfLine
End Sub

can be called like

Foo( "a" : 123  )
Foo( "a" : 123  ,  "b" : 345 )
Foo( "b" : 345  ,  "a" : 123  )

but again INSIDE the method you have to do all the work to grab the named parameters and use them as appropriate

Assuming action returns an integer…

Function Operator_Convert As Integer Return self.action End Function

But as Norman said, there are probably better ways. operator_convert could lead to confusing code down the road.

You could also consider a class that just holds the parameters/defaults and a function/functions that take that class as the argument.

DIM args AS NEW FnArgs
args.a = 123
args.b = 234
args.c = 345
args.d = 456
args.e = 567
Result = Fn(args)

Jims suggestion of a parameter class is a good one as well

I had already tried that. It works, but it is messy, in that now I need a companion class for every method. Better to embed the method into the class, as I explained near the top of this thread.

What I really want is to be able to declare Properties within a Method, so then I could do the original code I want:

DIM f AS NEW Fn f.a = 123 f.b = 234 f.c = 345 f.d = 456 f.e = 567 Result = f

Then you’ll want to add the Operator_Convert function to the class.

Function Operator_Convert As Integer Return self.action End Function

It’s just a regular method. Xojo recognizes the name and allows you to assign the class as if it was the return type. The method is called to make the assignment.
Then you have the “Result = f” style you want.

Also, Operator_Lookup will sort of let you do that, you would just put a Dictionary behind it.

Jim: Can you tell me what I’m doing wrong?

Window1 has TextField_A and TextField_B that I enter numbers into
TextField_Result is the result of the Action Method under the Product Class

Within the Window1

[quote]Sub PushButton_Action() Handles Action
DIM p AS NEW Product
p.A = Val (TextField_A.Text)
p.B = Val (TextField_B.Text)
TextField_Result.Text = Str §
End Sub[/quote]

Within the Product Class:

[quote]Public Function Action() as Integer
RETURN Self.A * Self.B
End Function

[quote]Public Function Operator_Convert() as INTEGER
Return Self.Action
End Function[/quote]

When I run it, I get the following compiler errors

[quote]Window1.PushButton1.Action, line 4
There is more than one item with this name and it’s not clear to which this refers.
TextField_Result.Text = Str §[/quote]

[quote]Window1.PushButton1.Action, line 4
Type mismatch error. Expected String, but got Int32
TextField_Result.Text = Str §[/quote]

What am I doing wrong?

EDIT: Corrected Function Action() As Integer

I don’t understand it, but this works:

DIM p AS NEW Product p.A = Val (TextField_A.Text) p.B = Val (TextField_B.Text) DIM Result as INTEGER = p TextField_Result.Text = Str (Result)

Whereas this does not work:

DIM p AS NEW Product p.A = Val (TextField_A.Text) p.B = Val (TextField_B.Text) TextField_Result.Text = Str (p)

Sounds like the compiler isn’t as smart as you’d hope. What if you do p+0 instead?

[quote]Window1.PushButton1.Action, line 5
Undefined operator. Type Product does not define “Operator_Add” with type Int32
TextField_Result.Text = Str (p+0)[/quote]

str() doesn’t give the compiler enough clues. It could take any number type, or a date, a color etc…
Add another Operator_lookup and you don’t even need str()

Function Operator_Convert As String Return str(self.action) End Function