Page 1 of 1
FoxPro class syntax
Posted: Fri Oct 11, 2019 9:52 pm
by robert
Just a quick update to tell you that we are making good progress with the FoxPro class syntax,
The following is a sample program that I used to test some of the syntax. The sample shows:
- Property declaration
- Property initialization
- Add Object clause
- Method declaration
- Access methods
- Custom class and Collection Class to support
Code: Select all
FUNCTION Start() AS VOID
LOCAL oPerson //ASPerson
// VFP compatible object creation, Checks for type at runtime
oPerson := CreateObject("Person", "Fabrice","Foray")
oPerson := Person{"Fabrice","Foray"}
? "First:", oPerson:FirstName
? "Last :", oPerson:LastName
? "Full :", oPerson:
? "Address:"
? oPerson:Address:AddressBlock
WAIT
RETURN
DEFINE CLASS Address AS Custom
PUBLIC Street, Zip, City as STRING // note that we have added the AS Type clause,
// Possible (optional) modifiers are PUBLIC, PROTECT, HIDDEN, INTERNAL
Street = ""
Zip = ""
City = ""
FUNCTION AddressBlock_Access AS STRING // Access method
RETURN This.Street+CRLF+This.Zip+" "+This.City
ENDFUNC
END DEFINE
DEFINE CLASS Person AS Custom
// Untyped. properties
FirstName, LastName
FirstName = "John"
LastName = "Doe"
ADD OBJECT Address AS Address WITH Street = "Main Street 1", ZIP = "12345", City = "Phoenix"
// Access method
FUNCTION FullName_Access as string
RETURN This.FirstName+" "+This.LastName
ENDFUNC
// Init event handler gets called after object has been created.
PROCEDURE init(cFirst, cLast)
DODEFAULT()
FirstName := cFirst
LastName := cLast
END DEFINE
This code uses a Custom class in the X# runtime that contains Name/Value pairs for the properties. The compiler also generates real .Net properties that read/write from the name value collection.
FirstName property gets compiled to:
Code: Select all
public virtual XSharp.__Usual FirstName
{
get
{
return _GetProperty("FirstName");
}
set
{
_SetProperty("FirstName", value);
}
}
The addressblock access method (in C#):
Code: Select all
public virtual string AddressBlock => Street + "rn" + Zip + " " + City;
I hope this was interesting to some of you.
We are wrapping up this build for testing this weekend.
Robert
FoxPro class syntax
Posted: Sat Oct 12, 2019 5:37 am
by lumberjack
Hi Robert,
Robert van der Hulst wrote:Just a quick update to tell you that we are making good progress with the FoxPro class syntax,
Great work and looking good. Ok maybe I should rather let the VFP guys do the praise or bashing...
@Matt, Eric, VFP Lurkers...
FoxPro class syntax
Posted: Sat Oct 12, 2019 2:57 pm
by atlopes
This looks fantastic and promising, Robert. Kudos are in order.
I'll comment only on a VFP perspective.
In VFP, the _Access methods (which are events, actually) require the declaration of the associated property. In the cases of your example, FullName in Person class, and AddressBlock in the Address class would require a proper declaration.
All user-defined properties, as well as most of the base properties, may have accompanying _Access and _Assign methods, which basically should function as setters and getters destined to override the built-in ones.
For now, two and a half questions (that may already have been addressed elsewhere, probably):
1) Must properties be declared before their initialization? And what's the execution context of the initialization?
2) You skipped the This prefix when referencing FirstName and LastName in the Init method of Person. Was this on purpose? In VFP, this would generate Private variables and left the object's properties untouched.
Again: it's a great and inspiring job. Thank you.
FoxPro class syntax
Posted: Sat Oct 12, 2019 4:58 pm
by FoxProMatt
Robert - this looks good and useful when writing new X#.VFP code.
I wanted to show you a common class code sample you'll see in existing VFP code. Not everyone uses AddObject to get an auxiliary object on a class. See this example:
Would this compile in X# with the next release??
Code: Select all
DEFINE CLASS Person AS Custom
FirstName = "John"
LastName = "Doe"
oAddress = .null.
PROCEDURE init(cFirst, cLast)
This.oAddress = CreateObject("Address")
With This.oAddress
.Street = 'Main Street 1'
.ZIP = "12345"
.City = "Phoenix"
EndWith
DODEFAULT()
This.FirstName = cFirst
This.LastName = cLast
EndProc
END DEFINE
FoxPro class syntax
Posted: Sat Oct 12, 2019 5:47 pm
by lumberjack
Hi Antonio,
António Lopes wrote:This looks fantastic and promising, Robert. Kudos are in order.
Thanks for the feedback, great to see the VFP guys getting involved! I will not do a full reply since I feel Robert is the best guy to make such a reply, but will give some comments.
In VFP, the _Access methods (which are events, actually) require the declaration of the associated property. In the cases of your example, FullName in Person class, and AddressBlock in the Address class would require a proper declaration.
It is not required in X#, by design.
2) You skipped the This prefix when referencing FirstName and LastName in the Init method of Person. Was this on purpose? In VFP, this would generate Private variables and left the object's properties untouched.
By default X# will "know" that FirstName and LastName is of the class, hence no need for "this." prefix. If you have a
Then you need a "this." prefix, the LOCAL will take preference without the prefix.
FoxPro class syntax
Posted: Sat Oct 12, 2019 6:47 pm
by atlopes
Got your points, Johan, thank you very much.
My main concern is that even if, by design, it is not required for an accessible property to have been declared, _Access and _Assign events will be still available for control of regularly declared properties. They will, right?
There is also a particular This_Access method, but I'm sure we'll come to that later.
By default X# will "know" that FirstName and LastName is of the class, hence no need for "this." prefix.
Ok, copy that. But what about cursor fields that might be open in the current work area? Or
This is only optional on the left side of assignment statements and required otherwise?
By the way, is X# supporting the m-dot syntax to allow for explicit references to memory objects? I don't seem to have seen it in your and others' examples so far.
[I'll try to set up a machine for testing later on the week, I'm sure these questions could easily be answered with simple tests]
FoxPro class syntax
Posted: Sat Oct 12, 2019 7:50 pm
by lumberjack
Hi Antonio,
António Lopes wrote:Got your points, Johan, thank you very much.
My main concern is that even if, by design, it is not required for an accessible property to have been declared, _Access and _Assign events will be still available for control of regularly declared properties. They will, right?
Basically the default for properties in VFP is they are public hence they have by default access/assign, or in X# terms a GET/SET access.
There is also a particular This_Access method, but I'm sure we'll come to that later.
Yes we have something similar in X#:
Code: Select all
PROPERTY SELF[nID AS INT] AS STRING // SELF = THIS
GET
RETURN Str(nID, 10, 2)
END GET
SET
...
END SET
END PROPERTY
Ok, copy that. But what about cursor fields that might be open in the current work area? Or This is only optional on the left side of assignment statements and required otherwise?
X# uses currently the old FIELD->FieldName or you can have a FIELD x, y, z declaration, which would take preference and then you need this.x to access the object property.
By the way, is X# supporting the m-dot syntax to allow for explicit references to memory objects? I don't seem to have seen it in your and others' examples so far.
It was discussed already, but I think Robert need to answer that.
I'll try to set up a machine for testing later on the week, I'm sure these questions could easily be answered with simple tests]
Yes I agree, and we here to help. Good luck with the testing!
FoxPro class syntax
Posted: Sun Oct 13, 2019 10:12 am
by robert
Antonio,
1) you don't have to declare properties before initializing. And you can also write initializers for properties that are defined in the parent class. If you do, then your class will get overrides for these properties, but these overrides will write to the same location as the properties in the parent class.
2) The This. prefix is optional in .Net. If you had declared a local variable with the same name as the property then the This. prefix would have been mandatory, because when local variables have precedence over properties with the same name. If you would have used a different name for a variable that does not exist as local and also not as property then the compiler would have generated a private, but only when you have enabled the compiler option "/undeclared"
Robert
FoxPro class syntax
Posted: Sun Oct 13, 2019 10:14 am
by robert
Matt,
This should work, including DoDefault(), .null. and WITH .. ENDWITH
Robert
FoxPro class syntax
Posted: Sun Oct 13, 2019 10:18 am
by robert
Antonio,
If you declare fields with the FIELD FirstName, Lastname .... synax then identifiers will be seen as field name. Likewise if you declare memory variables with MEMVAR or initialize then with PUBLIC or PRIVATE then the identifiers will be mapped to dynamic memory variables. Identiers that are not declared as FIELD, MEMVAR or LOCAL are assumed to be instance fields or properties of the class (or STATIC/CLASS level properties).
We have looked at the m-dot syntax. At this moment only M-> works and indicates that the identifier following the ALIAS (->) operator is a dynamic memory variable.
From what I have seen FoxPro uses m-dot both for dynamic variables as well as LOCAL variables. In other words: M-dot means that something is NOT a field. That is somewhat ambiguous. We are looking at this.
In general, we have a potential problem with the use of Dotted names in FoxPro, which is sometimes very ambiguous:
m-dot - can be both a local and a dynamic variable
customer.FieldName can be a field in a workarea/cursor named customer , but also be the FieldName property of a (undeclared?) variable named customer.
Especially the last one is difficult to resolve at compiler time because both the undeclared variable as well as the workarea can be created/opened outside of the scope of the current function / method.
The customer->FieldName syntax does not have that problem, because the ALIAS (->) operator is only used for memvars and fields and never for properties.
We will probably translate the Customer DOT FieldName syntax to code that will resolve this at runtime (or throw a runtime error when there is no cursor or variable with the name "Customer".
Robert