Seite 1 von 1

Procedure als Parameter

Verfasst: 12.06.2013 14:24
von Skiller
Hallo Experten,
Ich frage, ob sowas überhaupt realisierbar ist und ich weiss auch, dass das Beispiel nicht funzt.
aber vielleicht ist es ja doch irgendwie möglich. Habe jedenfalls per Suche nichts gefunden.
DANKE!!!

Code: Alles auswählen

Procedure TestFunc(Value.i)
  Debug Value
EndProcedure

Procedure func(ParaFunc)
  Protected i
  For i = 1 To 10
    ParaFunc(i)
  Next
EndProcedure

func(TestFunc(x))

Moderation: Doppeleintrag vermülleimert.

Re: Procedure als Parameter

Verfasst: 12.06.2013 14:31
von bobobo
Wenn du richtig schreibst, dann klappt es auch mit dem Code :D

Code: Alles auswählen

..
For i = 1 To 10
  TestFunc(i)  ;<-- hier darf man sich nicht vertun :)
Next
..

Re: Procedure als Parameter

Verfasst: 12.06.2013 14:40
von ts-soft
Ich denke mal, er meint eher so etwas:

Code: Alles auswählen

Prototype TestFunc(Value.i)

Procedure TestFunc(Value.i)
  Debug Value
EndProcedure

Procedure func(ParaFunc)
  Protected myfunc.Testfunc = ParaFunc
  Protected i
  For i = 1 To 10
    myfunc(i)
  Next
EndProcedure


func(@Testfunc()) 

Re: Procedure als Parameter

Verfasst: 12.06.2013 16:18
von STARGÅTE
Der Vollständigkeitshalber, geht das auch ohne die Zwischenvariable:

Code: Alles auswählen

Prototype TestFunc(Value.i)

Procedure TestFunc(Value.i)
  Debug Value
EndProcedure

Procedure func(ParaFunc.Testfunc)
  Protected i
  For i = 1 To 10
    ParaFunc(i)
  Next
EndProcedure


func(@Testfunc()) 

Re: Procedure als Parameter

Verfasst: 12.06.2013 18:50
von bobobo
Bitte um Aufklärung.
Für was ist diese Verknotung letztlich brauchbar?

Re: Procedure als Parameter

Verfasst: 12.06.2013 18:58
von NicTheQuick
Du kannst der Procedure 'func' verschiedene andere Procedures des selben Prototypes 'TestFunc' übergeben, mit denen sie dann was anstellen kann. Z.B. könnte 'TestFunc' ja der Prototype für eine Metrik sein, also 'Prototype.d Metrik(*x.Punkt, *y.Punkt)'. Dann kann man verschiedene konkrete Implementierungen für Metriken bauen wie z.B. für die euklidische Metrik und die dann anderen Funktionen übergeben.
Eine weitere Möglichkeit wäre auch ein Callback wie es auch 'SetWindowCallback()' schon macht. Das kriegt auch einen Pointer zu einer Procedure, die bestimmte Parameter haben muss.

Re: Procedure als Parameter

Verfasst: 12.06.2013 20:17
von STARGÅTE
Das (wie ich finde) beste Beispiel ist die Funktion bzw. das Macro CustomSortList():

Code: Alles auswählen

Prototype.i CustomSortListComparisonCallback(*Element1, *Element2)

Structure CustomSortList
	Callback.CustomSortListComparisonCallback
	Quit.i
	*Element
EndStructure

Threaded CustomSortList.CustomSortList

Macro CustomSortList(LinkedList, ComparisonCallback)
	CustomSortList\Callback = ComparisonCallback
	Repeat
		CustomSortList\Quit = #True
		ForEach LinkedList
			CustomSortList\Element = @LinkedList
			While NextElement(LinkedList)
				If CustomSortList\Callback(CustomSortList\Element, @LinkedList)
					SwapElements(LinkedList, CustomSortList\Element, @LinkedList)
					CustomSortList\Quit = #False
				EndIf
			Wend
			ChangeCurrentElement(LinkedList, CustomSortList\Element)
		Next
	Until CustomSortList\Quit
EndMacro
Mit diesem Macro kann man eine beliebige LinkedList mit einer beliebigen Vergleichsfunktion sortieren lassen.
Hier zwei Beispiele, wie man Zahlen (ohne berücksichtigung des Vorzeichens) sortieren kann und eine strukturierte Liste zB nach Namen und zusätzlich nach Vorname sortieren kann:

Code: Alles auswählen

;- Beispiel 1

NewList Zahlen.i()
Define I.i

Procedure SortWithoutSign(*Integer1.Integer, *Integer2.Integer)
	If Abs(*Integer1\i) > Abs(*Integer2\i)
		ProcedureReturn #True
	EndIf
EndProcedure


RandomSeed(1)
For I = 1 To 10
	AddElement(Zahlen())
	Zahlen() = Random(200)-100
Next

Debug "Unsortiert:"
ForEach Zahlen()
	Debug Zahlen()
Next
Debug "Sortiert:"
CustomSortList(Zahlen(), @SortWithoutSign())
ForEach Zahlen()
	Debug Zahlen()
Next

;- Beispiel 2


Structure Person
	Name.s
	Vorname.s
EndStructure

NewList Person.Person()
Define I.i

Procedure SortPerson(*Person1.Person, *Person2.Person)
	If *Person1\Name > *Person2\Name
		ProcedureReturn #True
	ElseIf *Person1\Name = *Person2\Name And *Person1\Vorname > *Person2\Vorname
		ProcedureReturn #True
	EndIf
EndProcedure


RandomSeed(1)
For I = 1 To 10
	AddElement(Person())
	Person()\Name = Chr(Random(26)+65)
	Person()\Vorname = Chr(Random(26)+65)
Next

Debug "Unsortiert:"
ForEach Person()
	Debug Person()\Name+", "+Person()\Vorname
Next
Debug "Sortiert:"
CustomSortList(Person(), @SortPerson())
ForEach Person()
	Debug Person()\Name+", "+Person()\Vorname
Next
Unsortiert:
45
-64
22
83
-100
-76
1
-42
-15
68
Sortiert:
1
-15
22
-42
45
-64
68
-76
83
-100
Unsortiert:
T, E
Q, Y
A, D
N, H
L, W
T, T
Q, I
Y, B
C, E
C, C
Sortiert:
A, D
C, C
C, E
L, W
N, H
Q, I
Q, Y
T, E
T, T
Y, B

Re: Procedure als Parameter

Verfasst: 14.06.2013 14:23
von bobobo
cool
Bild