Operator overloading problem

In trying to find a method to assign a class property without using the property name (to be used in a scripted interface) I was hoping to make use of the Operator_Convert overload method like this:

Class Class1
	Dim X as Integer
	Dim ID as Integer
	Sub Operator_Convert(iVal as Integer)
		Self.X= iVal
	End Sub
End Class

Dim C as New Class1
C.ID = 1 
C = 2
MsgBox( "C.X = " + str(C.X) + ", C.ID = " + str(C.ID)  )

The message box reports: " C.X = 2, C.ID = 0". Apparently the Operator_Convert method does not create a copy of object C, but creates a new class instance.

That’s not what I expected. Assuming that the observed behavior is by design, I’m left with the question: Is there a way to do what I’m trying to do in Xojo?

Gerard.

[quote]
Sub Operator_Convert(iVal as Integer)
Self.X= iVal
End Sub[/quote]

[quote]C = 2 C.ID = 1 MsgBox( "C.X = " + str(C.X) + ", C.ID = " + str(C.ID) )[/quote]

Switch the order of the lines so you assign the ID second?

You should expect it to create an object since it’s documented to do so
From http://documentation.xojo.com/index.php/Operator_Convert
When you use the convert-to form of the operator, the compiler needs to create a new object implicitly so that you can copy data into it.

Jason, Brock, thanks for your replies. The thing is that I would normally want to change the .X property for a range of Class1 objecs that have been created earlier, each with a different value for ID. So the ID property varies when the C = 2 call is made. And I cannot use any additional code to retrieve it’s value for a specific instance.

Norman,

I guess is misread that as:
When you use the convert-to form of the operator, the compiler needs to create a new object implicitly so that it can copy data into it.

Not sure I follow ?

Maybe it should read

When you use the convert-to form of the operator, the compiler needs to create a new object implicitly so that data can be copied into the new instance.

Convert FROM forms create a new instance and they do NOT call your custom constructors
This is documented on the page I referenced

No, the manual is clear. it’s just that I was surprised (and a little aggravated to be honest) that the data of the original instance is not copied into the new one, which would have made my life at lot easier.

That would be the wrong behavior in most cases, though. Sorry about your aggravation, but it just doesn’t work that way. You’ll have to use simple property assignment or create a method to call on the instance. But in all cases, you’ll have to refer to the instance using dot notation.

I see. Why would that be the wrong behavior in most cases? One could reset properties to their default values where necessary in the Operator_Convert method. I still find it awkward to have a procedure call on a class instance creating a new instance of the class that is independent of the properties of the instance that the call was made on. That feels like something that should be belongs in a Constructor-like routine of the class. But I’m not really an IT expert.

But it acts as a constructor - not a copy constructor
A copy constructor would have copied the originals data

It behaves like you had done

Dim C as New Class1 C.ID = 1 C = new Class1 c.x = 2

except you get the NEW and assignment from one line of code

C = 2 isn’t calling a setter on class C that sets a value on an existing instance
Maybe thats why this seems odd to you

C = 2 in this code sample is short hand for

  1. create a new instance (almost exactly like using new Class1)
  2. calling a “setter” to set the X property

In a sense it does behave like

   dim c as new Class1(2)

if you defined Class1 to have a constructor like

Sub Constructor(iVal as integer) Self.X= iVal

And thats actually how it’s intended to behave

The name, “operator convert” is because this method, when defined, is intended to CONVERT FROM or CONVERT TO another type and there IS no instance

In the code you have you could do

[code]
Class Class1
Dim X as Integer
Dim ID as Integer
Sub Operator_Convert(iVal as Integer)
Self.X= iVal
End Sub
End Class

Dim C as Class1
C = 2
MsgBox( "C.X = " + str(C.X) + ", C.ID = " + str(C.ID) )[/code]

and things would all work
note that you have NOT created an instance anywhere using NEW so something has to create one

You could use a pair, a dictionary, or a class instead of an integer as parameter in Operator_Convert:

[code]Class Class1
Dim X As Integer
Dim ID As Integer
Sub Operator_Convert(param As Pair)
Self.X = param.Left
Self.ID = param.Right
End Sub
End Class

Dim C As New Class1()
C.ID = 1
C = 2 : C.ID
MsgBox("C.X = " + Str(C.X) + ", C.ID = " + Str(C.ID))[/code]

C = 2

What that reads is, “Create a C from the value 2”. You are converting a ‘2’ into a ‘C’, which implies creating a new C. It would be wrong to retain any previous values of C.

Guys, thanks for your concern and help. But I’m still not completely convinced. I accept that the Operator_Convert method is a type conversion operation, that creates a new blank class instance. That does make it a bit of an outsider in the set of Operator overloading methods, though. Imho there is an Operator overloading procedure missing that would do what I need and make the set complete. This procedure would perhaps be called ‘Operator_Assign’ or something like that.

Class Class1
Dim X as Integer
Dim ID as Integer
Sub Operator_Assign(iVal as Integer)
Self.X= iVal
End Sub
End Class

Dim C as new Class1
C = 2

C = 2 would read “Assign a value 2 to C” and would not make a new instance of Class1, but simply assign the value 2 to the X property of the instance, as dictated by the override. In fact, there might be an ‘Operator_Retrieve’ method as well, that does the reverse of my Operator_Assign proposal, resulting into

dim y as integer = C

renders y equal to 2 with an ‘Operator_Retrieve’ overload in the above. Then there are overides for all operators: +, -, *, /, \, ^, mod, negate, including the = assignment.

Anyway, I realize that I’m pushing it too far now. I will try to find another way, or accept being bound to use the expression C.X = 2 .

Thx.

You can use Operator_Convert to return a value (such as integer). It allows you to convert both ways.

[quote=205845:@Gerard Van Zee]Guys, thanks for your concern and help. But I’m still not completely convinced. I accept that the Operator_Convert method is a type conversion operation, that creates a new blank class instance. That does make it a bit of an outsider in the set of Operator overloading methods, though. Imho there is an Operator overloading procedure missing that would do what I need and make the set complete. This procedure would perhaps be called ‘Operator_Assign’ or something like that.

Class Class1
Dim X as Integer
Dim ID as Integer
Sub Operator_Assign(iVal as Integer)
Self.X= iVal
End Sub
End Class

Dim C as new Class1
C = 2

C = 2 would read “Assign a value 2 to C” and would not make a new instance of Class1, but simply assign the value 2 to the X property of the instance, as dictated by the override. In fact, there might be an ‘Operator_Retrieve’ method as well, that does the reverse of my Operator_Assign proposal, resulting into

dim y as integer = C

renders y equal to 2 with an ‘Operator_Retrieve’ overload in the above. Then there are overides for all operators: +, -, *, /, \, ^, mod, negate, including the = assignment.

Anyway, I realize that I’m pushing it too far now. I will try to find another way, or accept being bound to use the expression C.X = 2 .

Thx.[/quote]

You’ve described operator convert And because it does create an instance you could write

[code]Class Class1
Dim X as Integer
Dim ID as Integer
Sub Operator_Convert(iVal as Integer)
Self.X= iVal
End Sub
End Class

Dim C as Class1 = 2
C.ID = 1

MsgBox( "C.X = " + str(C.X) + ", C.ID = " + str(C.ID) )[/code]

in the code you have
The only issue I see is that you expect it to not create an instance but knowing that it does you can still make use of it

The problem is that I need to preserve the ID property when I execute:

C = 2

I think you are trying to overuse Operator_Convert so that you can try to simplify one line of code. In this case it is best to not use it and just modify C.X directly, it’s more clear and it works exactly as expected.

Agreed. However it’s not one line of code. The purpose is to create a part of a user interface that allows users to supply scripting code snippets to manipulate some predetermined class instances. Because the user never sees anything more complicated than simple single statements, the syntax

Variable1 = Variable2

will be perceived as more clear than

Variable1.Value = Variable2.Value

It’s merely the aesthetics that are my concern.