Seite 2 von 2
Re: ReplaceString(), FindString() unschlagbar?
Verfasst: 18.11.2022 19:10
von SMaag
Ich hab's geschafft! Es geht ohne Public _AddQuotes_
Man muss nur die Adresszuweisung in das Modul verlegen. Das ist alles!
Hier der geänderte Code
Code: Alles auswählen
DeclareModule Quotes
#STR_CHAR_DoubleQuote = 34 ; "
#STR_CHAR_SingleQuote = 39 ; '
Declare.s AddQuotes_Classic(String$, cQuote.c=#STR_CHAR_DoubleQuote)
Prototype.s AddQuotes(String$, cQuote.c=#STR_CHAR_DoubleQuote)
; Declare.s _AddQuotes_(*String, cQuote.c=#STR_CHAR_DoubleQuote) ; _AddQotes_ nur noch Private
Define MyAddQuotes.AddQuotes ; = @_AddQuotes_() ; die Adresszuweisung muss in's Modul
Define OhterAddQuotes.AddQuotes ; nur um zu sehen ob das geht!
EndDeclareModule
Module Quotes
Procedure.s AddQuotes_Classic(String$, cQuote.c=#STR_CHAR_DoubleQuote)
; ASCII-34 = ", ASCII-39 = '
ProcedureReturn Chr(cQuote) + PeekS(@String$) + Chr(cQuote)
;ProcedureReturn Chr(cQuote) + String$ + Chr(cQuote)
EndProcedure
Procedure.s _AddQuotes_(*String, cQuote.c=#STR_CHAR_DoubleQuote) ;
; ASCII-34 = ", ASCII-39 = '
ProcedureReturn Chr(cQuote) + PeekS(*String) + Chr(cQuote)
EndProcedure
MyAddQuotes = @_AddQuotes_() ; die Adresszuweisung im Modul und braucht _AddQuotes_ nicht mehr Public
EndModule
UseModule Quotes
Define s$, N, K, t_C, t_P, t_m
N = 100000
s$ = "Ich bin ein String und war ein String"
t_C = ElapsedMilliseconds()
For K=0 To N
res$ = AddQuotes_Classic(s$)
Next
t_C = ElapsedMilliseconds()-t_C
Debug "Classic : " + t_C + "ms"
Debug res$
Debug ""
t_P = ElapsedMilliseconds()
For K=0 To N
res$ = MyAddQuotes(s$)
Next
t_P = ElapsedMilliseconds()-t_P
Debug "Prototype : " + t_P + "ms"
Debug res$
Debug ""
MessageRequester("Ergebnis", "Classic : " + t_C + "ms" + #CRLF$ + "Prototype : " + t_P )
Re: ReplaceString(), FindString() unschlagbar?
Verfasst: 18.11.2022 19:55
von NicTheQuick
Axolotl hat geschrieben: 18.11.2022 18:39
Ich habe da mal eine Frage: Kann man die Procedure so auch in anderen Proceduren benutzen?
Ich verwende eigentlich immer Global oder Protected und Define dann in Verbindung mit Shared.
Na klar, nutz einfach "Global" statt "Define". Dann verhält es sich im Grunde wie eine echte Procedure.
Re: ReplaceString(), FindString() unschlagbar?
Verfasst: 18.11.2022 23:00
von SMaag
Na klar, nutz einfach "Global" statt "Define". Dann verhält es sich im Grunde wie eine echte Procedure.
Da muss man erst mal drauf kommen. Aber klar, wenn Define geht, dann muss auch Global funktionieren.
Hatte gerade das Problem, dass wenn man im Declare-Teil die Protypes mit Define verwendet, dann
sind sie trotz UseModul nicht nutzbar - Der Compiler bringt fehler.
Stellt man dann trotz UseModul noch den Modulnamen:: vor, dann geht's!
mit Global ist das nicht mehr nötig und es reicht UseModule
Re: ReplaceString(), FindString() unschlagbar?
Verfasst: 18.11.2022 23:14
von SMaag
Hier die Demo, damit man das mit Define und Global Testen kann.
Das Ergebnis! Immer Global verwenden, dann funktioniert das wie man erwartet!
Mit Define muss man innerhalb von Proceduren trotzdem noch Modul:: vorstellen.
Code: Alles auswählen
DeclareModule STR
Prototype.i ReplaceChar(String$, cSearch.c, cReplace.c) ; ProtoType-Function for ReplaceChar
Global ReplaceChar.ReplaceChar ; define Prototype-Handler for CountChar
;Define ReplaceChar.ReplaceChar ; define Prototype-Handler for CountChar
#STR_CharSize=2
EndDeclareModule
Module STR
Procedure.i _ReplaceChar(*String, cSearch.c, cReplace.c)
; ============================================================================
; NAME: _ReplaceChar
; DESC: !PointerVersion! use it as ProtoType ReplaceChar()
; DESC: Replace a Character in a String with an other Character
; DESC: To replace all ',' with a '.' use : ReplaceChar(@MyString, ',', '.')
; DESC: This a replacement for ReplaceString() only for a single Char
; DESC: and with direct *String Access. This is 2-3 tiems faster than
; DESC: ReplaceString().
; DESC: To UCase a single char use ReplaceChar(MyString, 'e', 'E')
; VAR(String$) : The String
; VAR(cSearch) : Character to search for and replace
; VAR(cReplace): the Replace Charcter (new Character)
; VAR(*RetVal_NoOfChars.Integer): Place here a Pointer to a PB Integer-Struct
; to get back the NoOfCharsFound/Replaced
; RET.s : The new String
; ============================================================================
Protected *char.Character ; Pointer to a virutal Char-Struct
Protected N
*char = *String
If *char
While *char\c ; until end of String
If *char\c = cSearch
*char\c = cReplace ; replace the Char
N + 1
EndIf
*char + #STR_CharSize ; Index to next Char
Wend
EndIf
ProcedureReturn N
EndProcedure
ReplaceChar = @_ReplaceChar() ; Bind ProcedureAdress to the PrototypeHandler
EndModule
UseModule STR
EnableExplicit
Procedure ShowIt()
Define s$ = "Hallo Hallo"
Define N
Debug s$
N = ReplaceChar(s$,'a', 'e') ; mit Golbal ReplaceChar.ReplaceChar ; geht das immer
; N = STR::ReplaceChar(s$,'a', 'e') ; mit Define ReplaceChar.ReplaceChar ; muss Modul vorgestellt werden
Debug "Ersetzungen = " + N + " : " + s$
N = ReplaceChar(s$,'H', 'B')
Debug "Ersetzungen = " + N + " : " + s$
EndProcedure
ShowIt()
Re: ReplaceString(), FindString() unschlagbar?
Verfasst: 19.11.2022 13:08
von NicTheQuick
Das war mir jetzt wiederum nicht bewusst. Gut zu wissen.

Re: ReplaceString(), FindString() unschlagbar?
Verfasst: 19.11.2022 13:23
von mk-soft
Allgemein:
Variablen innerhalb von Prozeduren mit Protected deklarieren (Nicht mit Define).
Variablen mit Define sind für MainScope und kann mit Shared in der Prozedur bekannt gemacht werden.
Variablen mit Global sind überall sichtbar
Bei Verwendung Modulen müssen Variablen die öffentlich sind in DeclareModule deklariert werden.
Es gelten aber die gleichen Regeln im wie bei Allgemein.
Re: ReplaceString(), FindString() unschlagbar?
Verfasst: 19.11.2022 14:41
von Axolotl
Ich benutze die Kombi Define und Shared gerne für (wie ich sie nenne Semiglobale Variablen).
Wenn eine Variable für die Verwendung innerhalb einer Prozedure durch Shared "freigegeben" werden muss gehört das für mich zu meiner Art der defensiven Programmierung.
Kleine Anmerkung zur u.g. Code-Zeile:
Die Zwei ist bei UNICODE richtig, bei ASCII wäre hier eine Eins richtig.
Hilfreich für Anwender von älteren PB-Compilern, denn seit einigen Versionen wird nur noch UNICODE unterstützt.
Code: Alles auswählen
#STR_CharSize=2 ; <--> #STR_CharSize=SizeOf(CHARACTER)
Re: ReplaceString(), FindString() unschlagbar?
Verfasst: 19.11.2022 16:58
von mk-soft
SizeOf(CHARACTER) ist eine Compiler Funktion und trägt beim kompilieren den Wert ein.
Also im Programm direkt verwenden ohne Zwischenvariable.
Re: ReplaceString(), FindString() unschlagbar?
Verfasst: 07.12.2022 14:24
von Benubi
Es lassen sich auch bei Modulen Variablen im Module/EndModule (also außerhalb von DeclareModule) definieren, aber dann sind diese quasi nur für das Modul intern sichtbar, und nicht mehr über das Module:: Prefix erreichbar. Hier sollte man aber auch direkt in den ersten Zeilen seine Variablen deklarieren, weil das durchaus auf den Scope Einfluß hat.
Daher mit dem Prefix kommt man nur an die Shared und Global Variabeln in Declare Teil, man kann aber auch welche im Module-Teil verstecken. Und ich denke Macros kann man auch direkt in den Declare Teil reintun, sonst ginge es eh nicht. Aber selbst bei einem UseModule sollten diese im Module Teil deklarierten Variablen privat bleiben.
Zum Modul Namespace gab es auch manchmal Problemchen innerhalb von Modulen, glaube ich, wenn man Variablen mehrfach deklariert in einer Prozedur dann kann der Kompiler es machmal nicht mitbekommen und es gibt Heisenbugs. Ich glaube aber das wurde gefixt und in der neueren Version gab es dann eine Fehlermeldung (bereits deklariert). Man sollte also dennoch immer ein wenig die Möglichkeit von Namens-Konflikten im Auge behalten. Es scheint jetzt aber ordentlich gehändelt zu werden:
Code: Alles auswählen
DeclareModule abc
; Kommentare einfügen oder entfernen um mit UseModule zu testen
; Global hallo_welt = 10
Declare GetHallo()
EndDeclareModule
Module abc
Global hallo_welt = 123
Procedure GetHallo()
ProcedureReturn hallo_welt
EndProcedure
EndModule
;Debug abc::hallo_welt
Debug abc::GetHallo()
UseModule abc
Debug hallo_welt
Debug GetHallo()
Das ist dann schneller als Shared zu implementieren auf die Art, aber ich weiß nicht ob es sich um die gleichen Speicher-Arten handelt welche verwendet werden, also ob globaler Speicher hier verwendet wird und sich das uU auf die Programmgeschwindigkeit negativ auswirken könnte, wie PB das intern händelt.