None of this post is meant to be negative. I'm just thinking out loud about a few things. I can't wait to get PB9.
I printed off the on-line help information for PB9's objects. I am trying to get a handle on it before my order for PB9 is finally filled.
I seem to understand it all but I did find it a little strange that the terminology for METHODS used "CLASS METHOD" to indicate a private method. I would have thought that "PUBLIC METHOD" or "PRIVATE METHOD" would be more intuitive because it would immediately signal to the reader the scope of the method. I guess that eventually "CLASS METHOD" will be burnt into my head to mean it is private to the Class. :)
Also, CREATE and DESTROY for Constructors and Destructors. Would have been cool if Constructor and Destructor could have also been accepted as aliases. :)
Not quite sure I understand the Enumerating Collections example in the Help. Are "InterfaceItem" and "InterfaceItems" already pre-existing interfaces for our use in all Classes or do we somehow need to add them to our Classes first? I still like VB's approach of using "For Each Item In Items" although I'm sure I'll get used to treating the collection like any other For/Next loop counted based on retrieving the number of objects first.
Maybe it's just me but why do new commands seem to take the form of STATEMENT VERB PARAMETER TO RESULT, I guess like the DDT functions do. It seems overly verbose. I mean GLOBALMEM ALLOC count TO vHndl. Okay, it works but vHndl = MEMALLOC(count) seems better at least in my opinionated eyes today. :)
#INLCUDE ONCE -- Perfect!
FORWARD REFERENCING -- Absolutely perfect!!!
I am also a little confused about the BUILD$ fnction. Is it really practical in it's current format? I mean, I see it as the means to overcome the overhead of constantly appending of strings but in practice how would you use it. It seems like all of the strings need to exist prior to calling the function in order to get the real benefits of it, otherwise you simply end up calling the BUILD$ function repeatedly using a small number of strings (still, I can see that being more efficient over simple concatenation). I wonder if it is anymore efficient than the current method I use based on Hutch's appending code. That code essentially leaves the buffer open allowing you to continue appending strings as they become available. Maybe I'm just not visualizing it in practice. I will give it a go once I get the new compiler. :)
Local nPos As Long
Local st As String
Local sBuffer As String
st = "some string containing some example text"
nPos = AppendStr2( nPos, sBuffer, StrPtr(st), Len(st) )
st = "another string containing even more text"
nPos = AppendStr2( nPos, sBuffer, StrPtr(st), Len(st) )
... etc... etc...
' Get the result of the appended string
st = Left$( sBuffer, nPos )
'//
'// Fast function for concatenating many strings
'//
Function AppendStr2( ByVal stPos As Long, _
ByRef sBuffer As String, _
ByVal Addon As Long, _
ByVal lenAdd As Long _
) Export As Long
#REGISTER None
Local pBuffer As Long
' If the buffer is not large enough to handle the adding
' of this string then we need to expand the buffer.
If stPos + lenAdd + 1 > Len(sBuffer) Then
sBuffer = sBuffer & String$( Max&(lenAdd, 32 * 1024), 0) ' increase 32K minimum
End If
' Copy the new string to the end of the buffer
pBuffer = StrPtr(sBuffer)
! cld ; Read forwards
! mov edi, pBuffer ; Put buffer address In edi
! Add edi, stPos ; Add starting offset To it
! mov esi, Addon ; Put String address In esi
! mov ecx, lenAdd ; length In ecx As counter
! rep movsb ; Copy ecx count Of bytes From esi To edi
! mov edx, stPos
! Add edx, lenAdd ; Add stPos And lenAdd For Return value
! mov Function, edx
End Function
Quote
Not quite sure I understand the Enumerating Collections example in the Help. Are "InterfaceItem" and "InterfaceItems" already pre-existing interfaces for our use in all Classes or do we somehow need to add them to our Classes first? I still like VB's approach of using "For Each Item In Items" although I'm sure I'll get used to treating the collection like any other For/Next loop counted based on retrieving the number of objects first.
It is no longer in the last version of the help file. It was a leftover of the previous help files, when using the Item property was the only compiler supported way of doing it.
Now you can use the standard IEnumVARIANT enumerator, that is what For... Each uses.
' Retrieve a reference to the collection's enumerator
DIM pEnum AS IEnumVARIANT ' // IEnumVARIANT interface
pEnum = pObj.NewEnum ' All collections have a NewEnum method or property
IF ISNOTHING(pEnum) THEN ... ' Exit
' Iterate through the collection of objects
DIM vItem AS VARIANT
DIM oItem AS DISPATCH <or class name> ' if using Automation
-or-
DIM oItem AS <interface name> ' if using direct calls
DO
' Retrieve a reference to the next object in the collection
' The first parameter is the number of items to fetch.
' The second parameter can be an array of variants.
' The third variable can be a long value that will receive the number
' of items fetched.
hr = pEnum.Next(1, vItem, BYVAL %NULL)
IF hr <> %S_OK THEN EXIT DO
' Assign the VT_DISPATCH variant to the object variable
oItem = vItem : vItem = EMPTY
IF ISNOTHING(oItem) THEN EXIT DO
' Do other calls
' ...
' ...
' ...
' Release the object
oItem = NOTHING
LOOP
>#INLCUDE ONCE -- Perfect!
Imo not..
Preventing the reinclusion as done before (#if NOT %DEF( ..) is better then include once.
What if a(n older) module does not have this keyword?
>InterfaceItems
I don't think PB uses the IEnumerator, the example code looks the ordinary way.
Code as shown above should be the better way (aka foreach)
Quote from: Edwin Knoppert on August 22, 2008, 08:46:14 PM
>#INLCUDE ONCE -- Perfect!
Imo not..
Preventing the reinclusion as done before (#if NOT %DEF( ..) is better then include once.
What if a(n older) module does not have this keyword?
You still can use #IF NOT %DEF( ..), or both at the same time. #INCLUDE ONCE means "include this file if it has not already been included".
Of course i understand but now it get's discouraged to insert these few lines.
#INCLUDE ONCE is very useful with big sets of include files like my new winapi files, that also use #IF NOT %DEF. With #IF NOT %DEF, the file has still to be parsed until #ENDIF is found. With #INCLUDE ONCE, the file is not parsed at all if it has already been included. Before it was implemented, I had problems because I was exceeding the limit of nesting levels.
Quote
Maybe it's just me but why do new commands seem to take the form of STATEMENT VERB PARAMETER TO RESULT, I guess like the DDT functions do. It seems overly verbose. I mean GLOBALMEM ALLOC count TO vHndl. Okay, it works but vHndl = MEMALLOC(count) seems better at least in my opinionated eyes today.
I always have disliked the use of statements instead of functions, mainly because you always have to use a variable for the result, e.g. you can't use IF MemAlloc(count) = 0 THEN...
QuoteI always have disliked the use of statements instead of functions
All SDK purist will dislike it, it is another form of DDT's propriatary syntax alike style 8)
And for me it envolves extra effort to remember the syntax to use it, i think i will keep using my own API encapsulation ;)
...
Quote from: José Roca on August 23, 2008, 06:42:41 AM
Quote
Maybe it's just me but why do new commands seem to take the form of STATEMENT VERB PARAMETER TO RESULT, I guess like the DDT functions do. It seems overly verbose. I mean GLOBALMEM ALLOC count TO vHndl. Okay, it works but vHndl = MEMALLOC(count) seems better at least in my opinionated eyes today.
I always have disliked the use of statements instead of functions, mainly because you always have to use a variable for the result, e.g. you can't use IF MemAlloc(count) = 0 THEN...
I've decided to use MACROS
James
#COMPILE EXE
#DIM ALL
MACRO FUNCTION ClipGetText()
MACROTEMP s
DIM s AS STRING
CLIPBOARD GET TEXT TO s$
END MACRO = s$
MACRO FUNCTION ClipSetText(Param)
MACROTEMP i
DIM i AS LONG
CLIPBOARD SET TEXT Param TO i
END MACRO = i
FUNCTION PBMAIN () AS LONG
LOCAL S1,S2 AS STRING
LOCAL RetVal AS LONG
S1 = "James Fuller"
IF ClipSetText(S1) THEN
?"No ReVal"
END IF
S2 = ClipGetText
?"S2 = ";S2
WAITKEY$
END FUNCTION
The use of MACRO enlarge the size of the resulting EXE, while a true function won't.
FUNCTION ClipGetText()
LOCAL s AS STRING
CLIPBOARD GET TEXT TO s
FUNCTION = s
END FUNCTION
...
Quote from: Patrice Terrier on August 23, 2008, 02:19:24 PM
The use of MACRO enlarge the size of the resulting EXE, while a true function won't.
FUNCTION ClipGetText()
LOCAL s AS STRING
CLIPBOARD GET TEXT TO s
FUNCTION = s
END FUNCTION
...
????
Macro = No stack frame which is 1 meg and function call = slower
James
Macro produces largest code when you use it as a replacement for standard subroutines or functions.
Because instead of having the subroutine or function only once in your code, you have it each time the macro code substitution is being done, and if you use this macro say 20 times in your code then you will see the difference in the resulting EXE size.
For example try these two examples based on your code, and tell me which one produces the smallest code size
1 - Using MACRO
MACRO FUNCTION ClipGetText()
MACROTEMP s
DIM s AS STRING
CLIPBOARD GET TEXT TO s$
END MACRO = s$
MACRO FUNCTION ClipSetText(Param)
MACROTEMP i
DIM i AS LONG
CLIPBOARD SET TEXT Param TO i
END MACRO = i
FUNCTION PBMAIN () AS LONG
LOCAL S1,S2 AS STRING
LOCAL RetVal AS LONG
S1 = "James Fuller"
IF ClipSetText(S1) THEN
?"No ReVal"
END IF
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
?"S2 = ";S2
WAITKEY$
END FUNCTION
2 - Using standard function
FUNCTION ClipGetText() AS STRING
LOCAL s AS STRING
CLIPBOARD GET TEXT TO s
FUNCTION = s
END FUNCTION
FUNCTION ClipSetText(BYVAL sParam AS STRING) AS LONG
LOCAL i AS LONG
CLIPBOARD SET TEXT sParam TO i
FUNCTION = i
END FUNCTION
FUNCTION PBMAIN () AS LONG
LOCAL S1,S2 AS STRING
LOCAL RetVal AS LONG
S1 = "James Fuller"
IF ClipSetText(S1) THEN
?"No ReVal"
END IF
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
S2 = ClipGetText
?"S2 = ";S2
WAITKEY$
END FUNCTION
They often forget that these calls are also functions.
So reducing one wrapper function isn't gonna help much..
You're right of course Patrice!!
My brain was polluted this morning working with Visual Basic 2008 Express Edition trying to get a PB COM server working with it. Duh....
James
"Macro = No stack frame which is 1 meg and function call = slower"
Functions can't possibly have a 1 MEG stack frame. The physical limit is 64K as the extreme maximum, typically much, much less (like tens or hundreds of bytes). You're probably thinking of a THREAD stack frame.
Best regards,
Bob Zale
PowerBASIC Inc.
Quote from: Bob Zale on August 24, 2008, 09:33:43 AM
"Macro = No stack frame which is 1 meg and function call = slower"
Functions can't possibly have a 1 MEG stack frame. The physical limit is 64K as the extreme maximum, typically much, much less (like tens or hundreds of bytes). You're probably thinking of a THREAD stack frame.
Best regards,
Bob Zale
PowerBASIC Inc.
No I got it from here??
http://www.powerbasic.com/support/help/pbwin/index.htm
James
Each time a THREAD is created, a stack section (default=1M) is allocated for all functions/methods to use. No new stack memory is allocated for each function/method invocation.
Bob
Question is if a BASIC programmer should worrie about details on that a level.
I don't.. just like the register stuff.
Like a said, a call to Instr() or Mid$() are functions too, 'overhead' any way.
You would gain only one wrapper, your custom function.
So what's the point.. unless you write all code in assembly.
Quote from: Edwin Knoppert on August 24, 2008, 12:30:50 PM
Like a said, a call to Instr() or Mid$() are functions too, 'overhead' any way.
Not necessarily true and probably not. There is no need for a full stack frame on internal calls.
James
I already thought i would get this response, what about your function calling another custom procedure?
It's really a nonsense discussion.
Maybe suitable for rocket sience..
The time, the final API Call for the clipboard uses is much longer, then the MACRO or the Function at that place.
And alltogether, there is not even in phantasie a scenario thinkable in which any of these timedifferences would play any role hehehe.
At least not for the Clipboard call.
Even in very high time-critical situations, the calling of a PB Sub or Function is not a problem and can even be an advantage because of the use and new Assignement of REGISTER Variables.
MACROS are in theory faster, but it really depends on the situation, because the CPU caching (strategy?) and the REGISTER usage plays a role.
In the situation with the Clipboard from before, none of all these aspects is of any real Usage, because we don't need to read or set the Clipboard >100.000 times each seconds.
Or did I miss something here :-).
Macro? Function? blah blah blah.... none of that is important because I JUST GOT MY PB9 !!!! :D
I'll be tucked away for a week playing with this thing. Sweeeeeeeeeeet!
I believe that calls for a Woo-Hoo! Ok, so I'm just a tiny bit biased... {smile} Thanks for kind words and the excitement.
Bob Zale
PowerBASIC Inc.
I I'd also like just to get a nice house or a farm on the countryside,
have a computer, the new PB 9, a whirlpool - somebody who looks for alldays work ....
And then do a some month not much more then just enhance all my old ( old is everything before PB 9 :-) ) Code with the new possibilities.
But we'll see when it can happen.
Theo, good point - I wish also that I could update all of my old code. I thought about a couple of them last night but I think that I am not going to bother. I'll use PB9 in my next project rather than try to retrofit it into my old code. There's never a shortage of new projects! :)
Maybe I'll win the lottery and then be able to program full time!
Apparently, I'm one of the few that are using the new COM support for COM programming instead of OOP :)
:) I'll have a HUGE need for COM in my next programming project. It will involve a lot of Word, Excel and Outlook manipulation.... but, for now, I'll be using COM for OOP. Baby steps for me. My brain can only handle so much.
;D
To save you some head scratching, don't try to use EXCEL with direct calls; use OBJECT GET/CALL... Although EXCEL's type library lists dual interfaces, they return pointers to the dispatch interfaces, so trying to use them will end in frustration and GPFs.
Jose says he is doing com without oop and the new pb9 has oop that is com. I know that there is oop without com in other languages but I would like some clarification about the new pb9 oop. Is the new implementation of objects in pb9 exclusively com technology that is packaged in a clever way?
Is all of oop in powerbasic just com in a easy to use syntax? Does this mean that there is some advantage of oop that is not in the new compiler because of how it was implemented? Even strong advocates of oop like the inventor of python think that multiple inheritance causes more trouble than it solves so I am not looking for something like that.
I am attracted to the idea that powerbasic has used a proven "off the shelf" technology from Microsoft if I have the right understanding. Do I?
Quote
Is the new implementation of objects in pb9 exclusively com technology that is packaged in a clever way?
You bet.
Quote
Does this mean that there is some advantage of oop that is not in the new compiler because of how it was implemented?
Sure, but why everybody is talking about OOP and don't pay attention to what is for me more important and powerful, like the ability to use and write low-level COM servers? Can you use DirectX 9 with VB6?
Quote
Even strong advocates of oop like the inventor of python think that multiple inheritance causes more trouble than it solves so I am not looking for something like that.
Using COM classes you get clean and reusable objects that are self contained. Using multiple inheritance, you get MFC ;)