ProcedureReturn und Arrays

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
4Planes
Beiträge: 37
Registriert: 19.11.2020 17:08

ProcedureReturn und Arrays

Beitrag von 4Planes »

In der Dokumentation heißt es:
ProcedureReturn kann nicht verwendet werden, um ein Array, eine Linked List oder eine Map zurückzuliefern, übergeben Sie zu diesem Zweck das Array, die Linked List bzw. die Map als Parameter an die Prozedur.
Also mache ich eben das: Ich übergebe ein im Hauptcode definiertes Array als Parameter der Prozedur oder greife innerhalb der Prozedur per Shared auf das Array zu.

Dazu habe ich nun zwei Fragen:
1.) Warum kann eine Prozedur kein Array oder eine Liste ausgeben? Das wäre doch sehr praktisch. Das Schöne an einer Prozedur ist ja, dass sie aus Sicht des restlichen Codes eine Blackbox ist. Im Hauptcode muss ich mir keine Gedanken darum machen, wie eine Prozedur im Innern funktioiniert. Ich muss nur wissen, welche Parameter sie hat und was sie ausgibt. Diese schöne Funktionsweise wird hier zerstört, weil ich im Hauptcode ein Array erstellen muss, damit die Prozedur überhaupt funktioniert.

2.) Gibt es eine elegantere Lösung als das, was ich bisher mache? Wie geht man am besten damit um, wenn eine Prozedur dazu dienen soll, mehrere Zahlen, Strings, Daten, etc. zusammenzustellen und auszugeben?
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8679
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Re: ProcedureReturn und Arrays

Beitrag von NicTheQuick »

Leider können Purebasics Procedures nur native Datentypen zurückgeben. Das ist schon immer so und ich befürchte, dass es auch immer so bleiben wird. Viele wünschen sich diese Funktionalität schon lange, also die Möglichkeit Arrays, Listen, Maps oder einfach strukturierte Variablen zurückzugeben. Das einzige, was da noch in die Nähe kommt, sind Pointer. Die muss man aber der aufrufende Code später selbst wieder freigeben. Hier ein Beispiel:

Code: Alles auswählen

EnableExplicit

Structure Dir
	path.s
	error.i
	List dirs.s()
	List files.s()
EndStructure
Procedure.i GimmeFiles(path.s)
	Protected *dir.Dir = AllocateStructure(Dir)
	Protected hDir.i, entry.s
	
	*dir\path = path
	
	hDir = ExamineDirectory(#PB_Any, path, "*")
	If hDir
		*dir\error = #False
		While NextDirectoryEntry(hDir)
			entry = DirectoryEntryName(hDir)
			
			If entry = "." Or entry = ".."
				Continue
			EndIf
			
			Select DirectoryEntryType(hDir)
				Case #PB_DirectoryEntry_File
					If AddElement(*dir\files())
						*dir\files() = entry
					EndIf
				
				Case #PB_DirectoryEntry_Directory
					If AddElement(*dir\dirs())
						*dir\dirs() = entry
					EndIf
			EndSelect
		Wend
	Else
		*dir\error = #True
	EndIf
	
	ProcedureReturn *dir
EndProcedure

Define *dir.Dir = GimmeFiles(GetHomeDirectory())

Debug "All folders in " + *dir\path
ForEach *dir\dirs()
	Debug " [D] " + *dir\dirs()
Next

Debug "All files in " + *dir\path
ForEach *dir\files()
	Debug " [F] " + *dir\files()
Next

; Wieder freigeben
FreeStructure(*dir)
Bild
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6999
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: ProcedureReturn und Arrays

Beitrag von STARGÅTE »

4Planes hat geschrieben:Diese schöne Funktionsweise wird hier zerstört, weil ich im Hauptcode ein Array erstellen muss, damit die Prozedur überhaupt funktioniert.
Das musst du doch so oder so? Denn wenn deine Prozedur nun ein Array zurück geben würde, dann musstest du doch dieses Array genauso im Hauptcode definieren, wie du jede andere Variable definieren musst. Oder wo soll das Array sonst "hin".
Pseudocode:

Code: Alles auswählen

Define Dim Array.d(0)
Array() = FülleArrayMitZahlen(10)
Daher ist in meinen Augen der in PB zu verwendende Code nicht "zerstört":

Code: Alles auswählen

Procedure RandomList(Array Doubles.d(1), Length.i)
	Protected I.i
	Dim Doubles(Length)
	For I = 0 To Length-1
		Doubles(I) = Random(10000)*0.0001
	Next
EndProcedure

Define Dim Test.d(0)

RandomList(Test(), 5)

Debug ArraySize(Test())
Debug Test(0)
Debug Test(1)
Debug Test(2)
Debug Test(3)
Debug Test(4)
4Planes hat geschrieben:Wie geht man am besten damit um, wenn eine Prozedur dazu dienen soll, mehrere Zahlen, Strings, Daten, etc. zusammenzustellen und auszugeben?
Üblicherweise musst man dafür eine Struktur deren Pointer an die Prozedur übergeben wird, und dann in ihr gefüllt wird:

Code: Alles auswählen

Structure Beispiel
	String.s
	Zahl.i
	Float.f
EndStructure

Procedure Fill(*Beispiel.Beispiel)
	*Beispiel\String = "Hallo"
	*Beispiel\Float = 3.14
	*Beispiel\Zahl = 123
EndProcedure

Define Beispiel.Beispiel

Fill(Beispiel)

Debug Beispiel\String
Debug Beispiel\Float
Debug Beispiel\Zahl
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Antworten