Page 1 of 2

The ability to Create non-visual Classes

Posted: Thu Nov 11, 2010 8:47 pm
by swhite
Hi

I would like to request the ability to define classes and create instances. I am not asking for everything to be OOP but just the ability to define non-visual classes with properties, methods, events etc. and use instances of those classes in my code.

Thanks,
Simon

Re: The ability to Create non-visual Classes

Posted: Thu Nov 11, 2010 10:24 pm
by Trond

Code: Select all

Prototype P_MyClass_Shout(*Self, Msg.s)

Structure MyClass
  Name.s
  Shout.P_MyClass_Shout
EndStructure

Procedure MyClass_Shout(*Self.MyClass, Msg.s)
  MessageRequester("Shout!", Msg + " from " + *Self\Name + "!")
EndProcedure

Procedure MyClass()
  *Self.MyClass = AllocateMemory(SizeOf(MyClass))
  InitializeStructure(*Self, MyClass)
  *Self\Shout = @MyClass_Shout()
  ProcedureReturn *Self
EndProcedure


*Bill.MyClass = MyClass()
*Bill\Name = "Bill"

*Bob.MyClass = MyClass()
*Bob\Name = "Bob"

*Bill\Shout(*Bill, "Hello world!")
*Bob\Shout(*Bob, "Goodbye, world!")

Re: The ability to Create non-visual Classes

Posted: Thu Nov 11, 2010 11:16 pm
by Mistrel
The address of a particular object's method can't be obtained for callbacks. Sure, you can get a "general" procedure address and pass the object around. But that really defeats the purpose of encapsulation.

Code: Select all

Prototype P_MyClass_Shout(*Self, Msg.s)

Structure MyClass
  Name.s
  Shout.P_MyClass_Shout
EndStructure

Procedure MyClass_Shout(*Self.MyClass, Msg.s)
  MessageRequester("Shout!", Msg + " from " + *Self\Name + "!")
EndProcedure

Procedure MyClass()
  *Self.MyClass = AllocateMemory(SizeOf(MyClass))
  InitializeStructure(*Self, MyClass)
  *Self\Shout = @MyClass_Shout()
  ProcedureReturn *Self
EndProcedure


*Bill.MyClass = MyClass()
*Bill\Name = "Bill"

*Bob.MyClass = MyClass()
*Bob\Name = "Bob"

; *Bill\Shout(*Bill, "Hello world!")
; *Bob\Shout(*Bob, "Goodbye, world!")

Debug @MyClass_Shout()
Debug @*Bill\Shout()
Always having to pass "*Self" is also annoying.

Re: The ability to Create non-visual Classes

Posted: Fri Nov 12, 2010 11:45 am
by Trond
Mistrel wrote:The address of a particular object's method can't be obtained for callbacks. Sure, you can get a "general" procedure address and pass the object around. But that really defeats the purpose of encapsulation.
Huh?!?

Code: Select all

Debug @MyClass_Shout()
Debug *Bill\Shout

Re: The ability to Create non-visual Classes

Posted: Fri Nov 12, 2010 2:20 pm
by Mistrel
My debug window says:

Code: Select all

4199281
4199281
The address result from both cases is the general class procedure (similar to a static method) instead of the object's method, as one might expect in OO. You could pass the object instead of a callback and further increase ambiguity.

For example, you can't mix OO methods where a procedural function is expected since you can only pass the object itself. Because there is no support for interfaces or abstract classes or type checking to enforce it, it's impossible to guarantee specific functionality.

If PureBasic were to support this it would first need to support some way of defining a class interface for inheritance. And because there is no type checking for pointers, the next logical step would be to add pass-by-reference so that an object's type can be checked like any other type. This would avoid having to type pointers.

And for those who don't know and might be quick to reply, the "Interface" keyword in PureBasic is not the same as a class interface for use with inheritance.

Re: The ability to Create non-visual Classes

Posted: Fri Nov 12, 2010 5:36 pm
by Trond
Mistrel wrote:My debug window says:

Code: Select all

4199281
4199281
The address result from both cases is the general class procedure (similar to a static method) instead of the object's method, as one might expect in OO.
Huh? The object's method is returned, because it's the same as the static method. If you override the method in a specific instance, or in a descended class, it will return the new address.

This works the same as in C++, except in C++ you can't get to the actual address ("ISO C++ forbids taking the address of a bound member function to form a pointer to member function.")

Re: The ability to Create non-visual Classes

Posted: Sat Nov 13, 2010 1:40 am
by Mistrel
You're right. My mistake. :x

I do support this request, however. Defining visual classes would be very helpful.

Re: The ability to Create non-visual Classes

Posted: Fri Dec 10, 2010 5:03 pm
by swhite
Hi

Yes visual classes would be nice but they would I assume be a lot more work. In my case most of my front ends are are or will be Web Browser based so for me just having the ability to define classes that do not require any visual representation is fine and I think would be a great feature for an already great product. The speed of PB is allowing me to develop what amounts to an application server for web browser applications.

The ability to use procedural code and classes is a nice combination. I used it a lot in a previous development environment that supported both programming methods.

Simon

Re: The ability to Create non-visual Classes

Posted: Sat Dec 11, 2010 2:13 am
by netmaestro
Interfaces are cleaner than prototypes and with a virtual table in a datasection there is no need to pass a *self pointer. Take a look at srod's tutorial on nxsoftware.com "using OOP in Purebasic", he does a good job of explaining the approach.

Re: The ability to Create non-visual Classes

Posted: Sat Dec 11, 2010 4:08 am
by swhite
netmaestro wrote:Interfaces are cleaner than prototypes and with a virtual table in a datasection there is no need to pass a *self pointer. Take a look at srod's tutorial on nxsoftware.com "using OOP in Purebasic", he does a good job of explaining the approach.
Thanks for the link the article is very helpful.

Simon

Re: The ability to Create non-visual Classes

Posted: Sat Dec 11, 2010 8:20 pm
by Blood
netmaestro wrote:Interfaces are cleaner than prototypes and with a virtual table in a datasection there is no need to pass a *self pointer.
Agreed! Prototypes aren't really suitable because of passing *self all the time. Interfaces are cleaner.

Still, it would be nice to have fully supported OOP integrated in PB for serious work.

Re: The ability to Create non-visual Classes

Posted: Sat Dec 11, 2010 9:22 pm
by PMV
netmaestro wrote:Interfaces are cleaner than prototypes and with a virtual table in a datasection there is no need to pass a *self pointer. Take a look at srod's tutorial on nxsoftware.com "using OOP in Purebasic", he does a good job of explaining the approach.
Where ever the vtable points to, you never need to pass the *self pointer with Interfaces. :wink:

Prototypes are for better handling of DLLs, not to replace Interfaces.

MFG PMV

Re: The ability to Create non-visual Classes

Posted: Sat Dec 11, 2010 9:54 pm
by Trond
Interfaces make it difficult to allow instances to override methods.

Re: The ability to Create non-visual Classes

Posted: Mon Dec 13, 2010 4:45 pm
by swhite
Trond wrote:Interfaces make it difficult to allow instances to override methods.
I often use the following pattern to avoid overridding methods:
Interface
myMethod
EndInterface

Procedure myMethod
If myMethodPre()
myMethodExec()
EndIf
myMethodPost()
This allows me to put the default method code in myMethodExec and if I want to override it I simply put my code in myMethodPre() and return 0. This pattern creates a shallow inheritance hierarchy and greatly reduces the number of classes I need.

Re: The ability to Create non-visual Classes

Posted: Mon Dec 13, 2010 5:29 pm
by PMV
Trond wrote:Interfaces make it difficult to allow instances to override methods.
The vtable points to a list of pointers to the procedurs. If you want to change the
call of one procedure, you only need to override this single pointer. That is the same,
if you want to override the pointer of a prototype.

MFG PMV