fbpx
Welcome, Guest
Username: Password: Remember me
This public forum is meant for questions and discussions about Visual FoxPro
  • Page:
  • 1

TOPIC: FoxPro syntax, Properties and fields

FoxPro syntax, Properties and fields 1 week 3 days ago #10613

  robert's Avatar Topic Author robert Offline Posts: 1158
I have been working on the FoxPro language support yesterday and have the following questions:

1) In FoxPro all classes (have to) inherit from a base class. The ultimate base class is Custom. This is not just an empty class, because it also provides quite a few properties, events and methods. For example properties like name, left, right, Events like Init, Error and Destroy and methods like AddObject, AddProperty etc.
What do you think, should we allow classes (declared with the FoxPro class definition syntax) to inherit from 'nothing' (i.o.w. from System.Object), which also means that these objects will only have the normal .Net methods such as GetType() GetHashCode() and ToString().
We could also add a compiler option that determines that when no base class is defined your class either inherits from System.Object or from XSharp.FoxPro.Custom.

2) The FoxPro class syntax speaks of "Properties" and not of "Fields" or "Instance variables"
DEFINE CLASS ClassName1 AS ParentClass 
   [[PROTECTED | HIDDEN] PropertyName1, PropertyName2 ...]
   [[.]Object.]PropertyName = eExpression ...]

What would you expect that happens when this is compiled to .Net. Should PropertyName1 etc. become a 'real property' (with a getter and setter) or should they be compiled into a Field.
The problem with compiling it to a field is that we sometimes see a syntax like this:
DEFINE CLASS Animal as custom
Species    = "Animal"
ENDDEFINE

DEFINE CLASS Dog AS Animal
Species    = "Dog"
ENDDEFINE

If we compile "Species" to a field then the Dog class will try to redefine the field in the parent class.
Our compiler will then produce the warning:
warning XS0108: 'Dog.Species' hides inherited member 'Animal.Species'. Use the new keyword if hiding was intended.

From what I have seen FoxPro declares everything as "real" properties and somehow stores name/value pairs in an invisible collection inside each object and both Species in the Animal class and in the Dog class read/write from the same collection. So all these properties are virtual as well
So my current thinking is to generate .Net properties from this and make these virtual so they can be overwritten in a child class. We can also add a collection, but we can also create a backing field. In case of a property that overrides a parent property we can change the getter and setter and redirect the call to the parent property.
But that would mean that you can't create fields with the current FoxPro syntax.
I see a couple of solutions:
a) with a special compiler option you can tell the compiler to generate fields or properties. When you generate fields you will get a warning when you redefine a field in subclass
b) we always generate properties but add a special syntax to declare fields, something like
DEFINE CLASS ClassName1 AS ParentClass 
   [[PROTECTED | HIDDEN] FIELD Field1, Field2 ...]
   FIELD FieldName = eExpression ...]
Btw: our current definition allows you to specify the types for Fields/Properties:
[[PROTECTED | HIDDEN] PropertyName1, PropertyName2 ...] [AS DataType]

3) All methods inside FoxPro seem to be virtual. This was also the case for Visual Objects. We have a compiler option that does this automatically.

4) The ADD OBJECT syntax creates a property (field?) and sets the value of the property to a new object of the specified type and allows to set initial values for some properties of this new object. What is not clear to me is if this object is also automatically added to a collection of children (controls) in the class ?

5) Now that we move FoxPro to .Net we will also be able add new functionality. So far we have added the following (for free because it is there in our compiler already)
- The ability to declare attributes on a type, property method etc
- The ability to add more (visibility) modifiers then just PROTECTED and HIDDEN. For example also INTERNAL,ABSTRACT, STATIC and SEALED
- The ability to define Generic types and methods
DEFINE CLASS MyStack<T> WHERE T IS NEW()
- All types can be specified in the Namespace.Type syntax. For example
CLASS MyTable as System.Data.DataTable


I have more questions but these can be handled later
I would value your input on this.

Robert
XSharp Development Team
The Netherlands

Please Log in or Create an account to join the conversation.

Last edit: by robert.

FoxPro syntax, Properties and fields 1 week 3 days ago #10615

  lumberjack's Avatar lumberjack Offline Posts: 543
Hi Robert,
I realise this is posted in the Private forum, but would it not be better to make it public? Seeing your comments on GitHub is in the public domain which I have already shared on some VFP forums. If this is in the public forum I can share on ProFox/Foxite/MS VFP Forum and hopefully get a better response from a broader audience.
Will wait for your feedback, or maybe Matt can also share his thoughts?

In principle I don't see an issue with your approach as with Antlr, but we probably need more input from VFP gurus.
______________________
Johan Nel
George, South Africa

Please Log in or Create an account to join the conversation.

Last edit: by lumberjack.

FoxPro syntax, Properties and fields 1 week 3 days ago #10616

  robert's Avatar Topic Author robert Offline Posts: 1158
Johan,

I have moved the topic.

Robert
XSharp Development Team
The Netherlands

Please Log in or Create an account to join the conversation.

FoxPro syntax, Properties and fields 1 week 3 days ago #10617

  lumberjack's Avatar lumberjack Offline Posts: 543
Hi Robert,
Thanks and I have shared on ProFox, Foxite and MS VFP Forum. Thanks also for opening the forum for replies!
______________________
Johan Nel
George, South Africa

Please Log in or Create an account to join the conversation.

Last edit: by lumberjack.

FoxPro syntax, Properties and fields 1 week 3 days ago #10618

  FoxProMatt_MattSlay's Avatar FoxProMatt_MattSlay Offline Posts: 175
Here is some code to show answer for question 4:
Local loContainer as Container
Local loTextbox as TextBox

loContainer = CreateObject("Container")

? loContainer.ControlCount
* Prints 0

loContainer.AddObject("MyTextbox", "Textbox")

? loContainer.ControlCount
* Prints 1

For Each loControl In loContainer.Controls FOXOBJECT
	? loControl.Name
EndFor

* Prints "MYTEXTBOX"  (For some reason VFP changes the name to uppercase)

Note that the FOXOBJECT clause at the end of the For Each loop is not *required*, but is something that can tell VFP it is processing a native FoxPro collection type. This make it run a little faster than in cases where you are iterating over a COM object collection or some other non-VFP type and it's a little slower as it probably requires different handling underneath the covers.

Please Log in or Create an account to join the conversation.

Last edit: by FoxProMatt_MattSlay.

FoxPro syntax, Properties and fields 1 week 3 days ago #10621

  robert's Avatar Topic Author robert Offline Posts: 1158
Matt,

Thanks for the example but that is not what I meant, but you helped me anyway:

What I meant was something like this
DEFINE CLASS MyContainer AS Container
ADD OBJECT MyTextBox as TextBox
ENDDEFINE

I tested this code and I see that it does indeed add the control to the collection
oObject = CREATEOBJECT("MyContainer")
? oObject.ControlCount
FOR EACH oControl IN oObject.Controls
	? oControl.Name
next

This shows that there is one control with the name MYTEXTBOX, and it does not matter if that control was added in the class definition or in code (like in your example)

So the ADD OBJECT clause in a class definition also seems to call the AddObject method.
And since that method is declared in the custom class this will work in all classes.

And this also has effect on my question 1): to support 'ADD OBJECT' the class needs to inherit from Custom or from another class with a similar AddObject() method.
If we allow classes to inherit from System.Object then we can't support this.

Robert
XSharp Development Team
The Netherlands

Please Log in or Create an account to join the conversation.

FoxPro syntax, Properties and fields 1 week 3 days ago #10623

  atlopes's Avatar atlopes Offline Posts: 5
Robert,

A few notes regarding this thread, so far.

The ADD OBJECT clause and the AddObject() method also set the Parent property of the added object to a reference to the container. In other cases in which the object is instantiated without being added to a container, the value of the Parent property will be undefined.

They are not completely equivalent because the ADD OBJECT clause can inhibit the Init event of the added object, while the AddObject() method can't.

Some containers can add objects by setting specific properties. For instance, the second line in
m.Pgf = CREATEOBJECT("PageFrame")
m.Pgf.Pages = 2

creates two contained pages in Pgf and name them Page1 and Page2.

Base classes in VFP do not have a common ancestor, and they don't derive from Custom or any other class. Therefore, all base classes are at the top of the class hierarchy.

There is an Empty class, that does not have properties or methods at first, and that cannot be subclassed. Properties can be added to an Empty object via the ADDPROPERTY() function - not to be confused with the AddProperty() method.

You can also create objects that are not instantiations of any class by SCATTER an open cursor into an object with properties that represents the fields of the cursor.

Please Log in or Create an account to join the conversation.

FoxPro syntax, Properties and fields 1 week 3 days ago #10624

  FoxProMatt_MattSlay's Avatar FoxProMatt_MattSlay Offline Posts: 175
Just some extra info here... ADD OBJECT is mostly (perhaps always) used to add a UI control to a UI class that is a container, like a Container, Form, Page, etc.

It seems to me that 99% of the code I've ever seen that has ADD OBJECT code is *generated* code from SCX or VCX assets, using an export-to-prg tool. It's often just done to create or show demo code so people can see code that works, or perhaps paste it into a prg file to run it for learning or testing purpose.

You will see a lot of example code like this in the VFP Help file, but only because that's about the only way they can show you other info about an Function or demo some other features of VFP.

In my entire app, I don't think I have a single line of ADD OBJECT code on a class in a prg. Some people may have that, but I don't think it is very common.

Of course, X# needs to handle it, I'm just trying to give you insight, that generally not many people really write UI code this way, to any large degree.

Please Log in or Create an account to join the conversation.

FoxPro syntax, Properties and fields 1 week 3 days ago #10626

  atlopes's Avatar atlopes Offline Posts: 5
Matt,

I beg to differ.

The ADD OBJECT clause is fundamental to the definition of complex objects in non-visual code and may have nothing to do with UI. You can find a few examples of extensive use of this in VFPX.

Please Log in or Create an account to join the conversation.

Last edit: by robert.

FoxPro syntax, Properties and fields 1 week 3 days ago #10627

  robert's Avatar Topic Author robert Offline Posts: 1158
Antonio
Thanks for your input.

Do you know if there is an overview somewhere of the different bases classes , or better of the complete class hierarchy ?

Anyway, this thread confirms to me that FoxPro classes are like the .Net ExpandObject in the System.Dynamic namespace.
This type allows you to dynamically add and remove properties at runtime. It is like a collection Key-Value pairs:
docs.microsoft.com/en-us/dotnet/api/syst...iew=netframework-4.8
So our compiler should not created fields for the properties declared in the class definition but create properties that write to the backing collection of the object.

Robert
XSharp Development Team
The Netherlands

Please Log in or Create an account to join the conversation.

Last edit: by robert.

FoxPro syntax, Properties and fields 1 week 3 days ago #10628

  lumberjack's Avatar lumberjack Offline Posts: 543
Hi Robert,

robert wrote: Antonio
Do you know if there is an overview somewhere of the different bases classes , or better of the complete class hierarchy ?

Is THIS what you looking for?
______________________
Johan Nel
George, South Africa

Please Log in or Create an account to join the conversation.

FoxPro syntax, Properties and fields 1 week 3 days ago #10629

  atlopes's Avatar atlopes Offline Posts: 5
Robert,

The list of VFP base classes can be found in docs.microsoft.com/en-us/previous-versio...ro/e9xttdtd(v=vs.80) - I hope the link gets through correctly.

Please Log in or Create an account to join the conversation.

FoxPro syntax, Properties and fields 1 week 3 days ago #10630

  lumberjack's Avatar lumberjack Offline Posts: 543
Takes some time, but I think in the same group THIS is also a good starting point to browse
______________________
Johan Nel
George, South Africa

Please Log in or Create an account to join the conversation.

Last edit: by lumberjack.

FoxPro syntax, Properties and fields 1 week 2 days ago #10632

  FoxProMatt_MattSlay's Avatar FoxProMatt_MattSlay Offline Posts: 175
@atlopes -

The ADD OBJECT clause is fundamental to the definition of complex objects in non-visual code and may have nothing to do with UI. You can find a few examples of extensive use of this in VFPX.


Please give me a couple of example projects that you are referring to?

Please Log in or Create an account to join the conversation.

Last edit: by FoxProMatt_MattSlay.

FoxPro syntax, Properties and fields 1 week 2 days ago #10636

  robert's Avatar Topic Author robert Offline Posts: 1158
Antonio,
I do know this list, but what I have not found is a diagram that shows which classes inherit from which and what the base classes in the hierarchy are. On this page everything is called "Base Classes" but I am sure that there is hierarchy in this list as well. Most likely all UI control classes inherit from Control.
I guess the easiest way to create such a diagram is to simply instantiate every class and query its ParentClass and BaseClass properties.

Robert
XSharp Development Team
The Netherlands

Please Log in or Create an account to join the conversation.

FoxPro syntax, Properties and fields 1 week 2 days ago #10638

  FoxProMatt_MattSlay's Avatar FoxProMatt_MattSlay Offline Posts: 175

I guess the easiest way to create such a diagram is to simply instantiate every class and query its ParentClass and BaseClass properties.


I tested this in VFP for you on about 10 classes:

As you can see, there is nothing exciting here... There is no magic low-level common base class underneath them all.

I give you the VFP code at the end in case you want to test further...
Class: Textbox ParentClass: Textbox BaseClass: Textbox 
Class: Container ParentClass: Container BaseClass: Container 
Class: Form ParentClass: Form BaseClass: Form 
Class: Grid ParentClass: Grid BaseClass: Grid 
Class: Page ParentClass: Page BaseClass: Page
Class: Column ParentClass: Column BaseClass: Column
Class: Checkbox ParentClass: Checkbox BaseClass: Checkbox
Class: Collection ParentClass: Collection BaseClass: Collection
Class: Editbox ParentClass: Editbox BaseClass: Editbox
Class: Control ParentClass: Control BaseClass: Control
Class: Custom ParentClass: Custom BaseClass: Custom


Here's the VFP code:
oClasses = CreateObject("Collection")

oClasses.Add('Textbox')
oClasses.Add('Container')
oClasses.Add('Form')
oClasses.Add('Grid')
oClasses.Add('Page')
oClasses.Add('Column')
oClasses.Add('Checkbox')
oClasses.Add('Collection')
oClasses.Add('Editbox')
oClasses.Add('Control')

oClasses.Add('Custom') 
oClasses.Add('Empty') &&Causes error accessing the .Class property

For Each cClass in oClasses
	
	oObject = CreateObject(cClass)
	? "Class: " + cClass + "   ParentClass: " + oObject.Class + "   BaseClass: " + oObject.BaseClass

EndFor

Please Log in or Create an account to join the conversation.

Last edit: by FoxProMatt_MattSlay.

FoxPro syntax, Properties and fields 1 week 2 days ago #10639

  robert's Avatar Topic Author robert Offline Posts: 1158
Matt,
Thanks.

As you can see, there is nothing exciting here... There is no magic low-level common base class underneath them all.

This is weird.
In all UI class hierarchies that I have worked with so far there is a control class as base class for textboxes, editboxes, checkboxes etc., so the form class can iterate its controls collection and work with the common properties. This is the case in MFC, Delphi, Visual Objects, various Java environments, .Net etc. Depending on the platform this class is called CControl, TControl, Control or something like that.
I am sure that under the hood something like this is also the case for FoxPro, but apparently the FoxPro devteam has decided to hide that for their users..

In Guineu there is a class ObjectBase which is the base class of all objects

Robert
XSharp Development Team
The Netherlands

Please Log in or Create an account to join the conversation.

FoxPro syntax, Properties and fields 1 week 2 days ago #10641

  atlopes's Avatar atlopes Offline Posts: 5
Yes, Robert, all VFP base classes are at the top of the class hierarchy.

Another key aspect that will require specific "hidden" behavior is the containership rules for the classes that have the capability. The list of container-type classes and the containership rules can be found in docs.microsoft.com/en-us/previous-versio...a9tc2%28v%3dvs.71%29 .

Please Log in or Create an account to join the conversation.

FoxPro syntax, Properties and fields 1 week 2 days ago #10642

  atlopes's Avatar atlopes Offline Posts: 5
Matt,

On top of my head, all of the projects that I submitted to VFPX. I'll have to check if others, too.

You can find extensive use of the ADD OBJECT clause in overHere, a library of classes to access and operate with the Here.com location platform web services.

Please Log in or Create an account to join the conversation.

FoxPro syntax, Properties and fields 1 week 2 days ago #10647

  lumberjack's Avatar lumberjack Offline Posts: 543
Hi Robert,

Post from the MS FoxPro forum by Tom Knauf:

Just some thoughts on that :

to my opinion the ultimate class is "empty". You can only use addproperty() to add propertys, optional with an initial value.

Here is a short example for an application object holding global variables :

oapp = newobject("empty") && new object (instance) of empty

addprop(oapp,"appname","Test") && adds a property of type char, value "Test"

addprop(oapp,"xversion",4711) && adds a property of type int, value 4711

addprop(oapp."activeuser","Tom")

Now this works

? oapp.xversion

oapp.activeuser = "Tim"

Unfortunately :-)this works, too : oapp.xversion = "Oh, now a char"

The value of a property can also be another object which has own propertys. So you can have an object of type form and use addprop() or GUI to add a property with another form and its propertys.

In foxpro terms fields are part of tables or cursors, propertys are propertys :-), this may confuse foxpro programmers and c# programmer

There is a commandpair scatter / gather which may cause confusion, too :

use adress

scatter memo name oadress && now you have an object oadress with all fieldnames as propertynames filled with the values of the fields

oadress.lastact = date() && set value of property lastact to current date

gather memo name oadress && write all values back to table

Sometimes we use addproperty to extend the "dataobject" built with scatter into a "businessobject" holding values not part of the table.

Regards

tom

BTW : scatter / gather is one of the commands I REALLY like and which I miss in .NET.

(yes I know LINQ, entity framework,... Thinks are getting better in .NET. Slowly.)
______________________
Johan Nel
George, South Africa

Please Log in or Create an account to join the conversation.

  • Page:
  • 1