Your code is essentially the same as mine.
The differences I can find:
Your class behaves as though it were a container for two variables, a string and an integer.
When my object is assigned a string and then an integer, it forgets it was a string and considers itself re-initialized. If it changes types it is re-initialized and not considered a change.
I wanted a generic object that could hold any type. FB does not handle generics as of yet. That is the reason I want my object to behave as though it was a single self aware variable and not a container type. It was never intended to hold both integer and string at the same time.
I even delved into your macro world a bit to see if I could improvise generics. But I couldn't come up with anything that wasn't really clunky, bizarre or that impressed me as useable.
The only other glaring thing to my eyes is that you shortened the code a little by using a boolean member var instead of a property. I may borrow that.
I was fooling around with trying to establish a base class that could be extended by whatever type you wanted rather than contain it all in one. In that aspect I ran into trouble with the lack of generics, so my base class ended up being only two abstract operator overloads. At that point it just didn't make sense to continue that direction. Thats where I was at when I rebuilt the object into what I posted. (That is the reason for the strange name "StateBase")
Also, you didn't provide an integer Cast. I still want to be able to do ? s * 12, etc.
But here is the latest (still not completely happy with it):
Code: Select all
As String _string_value
As Integer _int_value
As String _string_old_value
As Integer _int_old_value
As _type init_flag = _none
Declare Property IsChanged() As boolean
Declare Operator Cast() As String
Declare Operator Cast() As Integer
Declare Operator Let(ByRef txt As String)
Declare Operator Let(ByRef value As Integer)
operator StateVar.Cast() As String
If this.init_flag = _string Then
ElseIf this.init_flag = _int Then
operator StateVar.Cast() As Integer
operator StateVar.Let(ByRef value As String)
This._string_value = value
If this.init_flag = _none OrElse this.init_flag = _int Then
this.init_flag = _string
this._string_old_value = value
Operator StateVar.Let(ByRef value As Integer)
This._int_value = value
If this.init_flag = _none OrElse this.init_flag = _string Then
this.init_flag = _int
this._int_old_value = value
Property StateVar.IsChanged() As boolean
Dim As boolean b
If this.init_flag = _int Then
If this._int_value <> this._int_old_value Then
b = TRUE
If b = TRUE Then
this._int_old_value = this._int_value
ElseIf this.init_flag = _string Then
If this._string_value <> this._string_old_value Then
b = TRUE
If b = TRUE Then
this._string_old_value = this._string_value
Dim s As StateVar
s = "test"
? "test", s, s.ischanged
s = 12
? s * 12, s, s.ischanged
? 13, s, s.ischanged
? "test",s, s.ischanged
? "moo", s, s.ischanged
I will also explain why I want a self aware variable.
In the main loop of a program there is a printing of information to the screen, such as cursor location. This gets printed thousands of times because of the loop, even if the info doesn't change. With a self aware variable this re-print can be avoided.
As I type this out now I just got the idea that I can move that logic into the the cast overload and turf the 'if myvar.ischanged then". I should be able to just "print myvar" and let the cast do the check.
After posting a version using your system of a boolean variable 'is_changed' I realized it wasn't going to work. I deleted it.
Neither will your version work. The reason is that the variable must be able to tell the code whether its been changed since its been checked last
. In your code the member var is_changed is true and remains true until you change the variable value.
Therefore is_changed will work if it is a property that can then set the member var _is_changed to false after its been checked. This also means that a member print function is not workable either.
So I am reverting back to the version I posted here.