Seite 1 von 2
Integerübergabe ByRef
Verfasst: 29.07.2017 23:01
von Kurzer
Hallo zusammen,
nachdem ich seit ein paar Wochen in PHP eine Webanwendung programmiere, bin ich durch dessen Möglichkeiten etwas verwöhnt wie mir scheint.
"Nativ" werden in PureBasic ja nur Arrays, Listen und Maps als Referenz an Prozeduren übergeben.
In PHP kann jede Variable sehr einfach, nach Bedarf "byRef" übergeben (oder besser aus Sicht der Funktion "übernommen") werden, wenn man bei der Funktionsimplementation ein & vor die Variable schreibt.
Code: Alles auswählen
function Test($param1, &$param2) {
$param2 = 22;
}
$a = 10;
echo test(1, $a);
echo a$; // Wird 22 ausgeben
Param 2 wird dadurch automatisch "byRef" behandelt, also als Referenz auf die originale Variable außerhalb der Prozedur / Funktion.
Nun habe ich mir das in PureBasic wie folgt nachgebaut und frage mich, ob das die einzige Möglichkeit ist dies zu erreichen.
Code: Alles auswählen
Procedure test (*byref.integer)
*byref\i = 22
EndProcedure
a.i = 10
test (@a)
Debug a ; gibt 22 aus.
Re: Integerübergabe ByRef
Verfasst: 30.07.2017 07:36
von GPI
das einzige, was mir noch einfällt, wäre Macros zur Verschleierung zu Nutzen.
Code: Alles auswählen
Procedure __test (*byref.integer)
*byref\i = 22
EndProcedure
Macro test(variable)
__test(@variable)
EndMacro
a.i = 10
test (a)
Debug a ; gibt 22 aus.
Macht aber den Code etwas schlechter lesbar.
Re: Integerübergabe ByRef
Verfasst: 30.07.2017 10:32
von mk-soft
Schwieriger wird es bei Strings als ByRef zu übergeben.
Es kann nicht eine einfache String-Variable übergeben werden weil dann der Pointer zum String übergeben wird und nicht der Pointer zur Variable der den Pointer zum String enthält.
Code: Alles auswählen
;-TOP
Procedure foo(*inout.String, *value.integer)
*value\i + 100
*inout\s + " " + Str(*value\i)
EndProcedure
Global t1.String
Global v1 = 100
t1\s = "hello world"
Debug "Address of String: " + PeekI(t1)
Debug t1\s
foo(t1, @v1)
Debug "Address of String: " + PeekI(t1)
Debug t1\s
; Invalid Pointer to String
t2.s = "hello world"
Debug "Address of String: " + PeekI(@t2)
foo(@t2, @v1)
Debug "Address of String: " + PeekI(@t2)
Debug t2
Re: Integerübergabe ByRef
Verfasst: 30.07.2017 11:26
von uweb
Das ist ja mal eine nette Denksportaufgabe für den Sonntagmorgen.
*byref.integer kannte ich noch gar nicht.
Deswegen habe ich eine noch schlechter lesbare Lösung gebastelt.
Die ist zwar viel aufwendiger, aber wenn man schon von hinten durch die Brust ins Auge fasst sind Strings auch kein Problem mehr.
Ob das nun sinnvoll ist steht auf einem anderen Blatt.
Code: Alles auswählen
Structure Param
int.i
strg .s
EndStructure
; Die Grundidee ist es von Anfang an Felder statt Variablen zu nutzen:
Dim parameters.Param(1)
Macro a_i : parameters(1)\int : EndMacro
Macro hi_s : parameters(1)\strg : EndMacro
Macro params : Array parameters.Param(1) : EndMacro ; nur verkürzte Schreibweise
Declare Test(params)
Macro TestParam1 : parameters(0)\int : EndMacro
Macro TestParam2 : parameters(1)\int : EndMacro
Macro TestParam3 : parameters(0)\strg : EndMacro
Macro TestParam4 : parameters(1)\strg : EndMacro
Macro _Test(_TestParam1, _TestParam2, _TestParam3, _TestParam4)
; da auch Konstanten übergeben werden können:
parameters(0)\int=_TestParam1
parameters(1)\int=_TestParam2
parameters(0)\strg=_TestParam3
parameters(1)\strg=_TestParam4
Test(parameters())
EndMacro
Procedure Test (params)
TestParam2 = 22;
a_i = a_i + TestParam1 ; Das Macro für a_i ist global
TestParam4 = TestParam4 + TestParam3
EndProcedure
a_i = 10
hi_s = "Hello World!"
_Test(1, a_i," Nice to meet you.",hi_s)
Debug a_i
Debug hi_s
Re: Integerübergabe ByRef
Verfasst: 30.07.2017 12:31
von Nino
Kurzer hat geschrieben:"Nativ" werden in PureBasic ja nur Arrays, Listen und Maps als Referenz an Prozeduren übergeben.
uweb hat geschrieben:Code: Alles auswählen
; Die Grundidee ist es von Anfang an Felder statt Variablen zu nutzen:
Also Arrays (bzw. Listen oder Maps) nur deshalb benutzen, weil sie als Prozedurparameter als Referenz übergeben werden, auch wenn man sie sonst gar nicht braucht?
uweb hat geschrieben:Ob das nun sinnvoll ist steht auf einem anderen Blatt.
Jo.

Da würde ich doch lieber Zeiger nehmen, so wie hier im 1. Posting gezeigt.
Re: Integerübergabe ByRef
Verfasst: 30.07.2017 13:43
von GPI
Nino hat geschrieben:Also Arrays (bzw. Listen oder Maps) nur deshalb benutzen, weil sie als Prozedurparameter als Referenz übergeben werden, auch wenn man sie sonst gar nicht braucht?
Structuren gehen auch wunderbar
Code: Alles auswählen
Structure para
opt1.i
opt2.s
opt3.d
EndStructure
v.para
v\opt1=10
v\opt2="test"
v\opt3=4.5
Procedure test(*para.para)
Debug "test:"+*para\opt1+" "+*para\opt2+" "+*para\opt3
*para\opt1=33
*para\opt2="neo"
*para\opt3=9.9
EndProcedure
Debug "outside:"+v\opt1+" "+v\opt2+" "+v\opt3
test(v)
Debug "outside:"+v\opt1+" "+v\opt2+" "+v\opt3
Re: Integerübergabe ByRef
Verfasst: 30.07.2017 13:51
von Nino
GPI hat geschrieben:Nino hat geschrieben:Also Arrays (bzw. Listen oder Maps) nur deshalb benutzen, weil sie als Prozedurparameter als Referenz übergeben werden, auch wenn man sie sonst gar nicht braucht?
Structuren gehen auch wunderbar
Ja klar, die hat Kurzer ja von Anfang an verwendet.
bezeichnet nichts anderes als eine in PB bereis eingebaute Struktur. Natürlich bietet es sich je nach Situation an, ggf. best. "by Reference-Variablen" in einer selbstdefinierten Struktur zusammenzufassen.
Re: Integerübergabe ByRef
Verfasst: 30.07.2017 14:08
von Kurzer
Ich versuche die PHP Syntax gerade mit Macros zu imitieren, es scheitert aber daran, dass das Verkettungs-Zeichen # in Macros nicht mit einem * zusammen funktioniert.
http://www.purebasic.fr/english/viewtop ... 13&t=68850
Re: Integerübergabe ByRef
Verfasst: 30.07.2017 18:33
von uweb
Code: Alles auswählen
a_i = 10
hi_s = "Hello World!"
_Test(1, a_i," Nice to meet you.",hi_s)
Nach reichlichem Herumprobieren bin ich auf noch keine bessere Lösung für ByRef und Konstanten gekommen.
Mir ist schon klar, dass die Array-Lösung umständlich ist und nur fuktioniert weil sie die Konstantenwerte in ein Feld kopiert - also die Konstanten nicht wirklich ByRef behandelt.
Aber was wäre denn der bessere Weg ohne die Syntax zu vergewaltigen bzw um sie ggf. über Makros wiederherzustellen?
PS
Ich habe gerade beim Aufräumen noch etwas witziges wiedergefunden:
Code: Alles auswählen
Procedure _test (*byref1.integer, *byref2.integer)
*byref2\i = 22
EndProcedure
Macro test(variable1, variable2)
_test(@variable1, @variable2)
EndMacro
a.i = 10
test (1, a)
Debug a
Re: Integerübergabe ByRef
Verfasst: 30.07.2017 20:24
von Josh
Gerade zu Beginn meiner Pb-Zeiten war ich von der Parameterübergabe 'ByRef' in Pb auch nicht gerade begeistert.
Trotzdem halte ich nicht viel davon, wenn per Macro syntaktischer Zucker verstreut wird. Das macht es nur mühsamer, wenn nach ein paar Jahren ein Code angepasst werden muss oder gar der Code von anderen gelesen werden muss.