[PHP] $x uit de ene functie in de andere gebruiken

Pagina: 1
Acties:

  • Mithrandir
  • Registratie: Januari 2001
  • Laatst online: 20:21
Gelukkig, eindelijk een titel gevonden die wel kort genoeg was :D

Hier mijn probleem:

Ik heb een class, met 2 functies erin. In de ene functie maak ik een variabele, in de andere functie wil ik diezelfde variabele weer gebruiken. Hier mijn code:
PHP:
1
<?class Template{    /* functions */    function loadLayout()    {    $_layout = "<blaat>"    }    function printLayout()    {    print($_layout); /* DIT WERKT DUS NIET :(... $_layout moet worden doorgegeven aan printLayout door parameters; iets anders kan ik niet verzinnen :( */    }}?>

Ik heb het geprobeerd met global, maar dat werkte niet (de variabele wordt aangemaakt in een functie, en is daar dus niet global). En ik kan dus wel doen dat ik een functie zo aanroep

$_layout = $template->loadLayout();
en dat ik $_layout dan als global aanroep in de 2e functie (hoewel dat NIET mooi is natuurlijk, en dat wil ik dus niet).

Dus mijn vraag is niet "hoe kan ik dit doen", maar "hoe kan ik dit MOOI doen".

D2k wist het niet, dUSTY ook niet. Nu jullie :P (dusty zei: "met global". Dat werkte niet.)

/edit $*($#(#(&%#(#% TOPIX

Verbouwing


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Hmmzz.. dit is een probleem dat je met c/pascal op zou lossen mbv een call by reference ipv een call by value. Hiervoor heb je dus pointers nodig, en ik betwijfel of php deze heeft. Watje wel zou kunnen doen is die x wrappen in een nieuwe class, en deze meegeven aan je functies. Hierdoor kunnen alle functies beschikken over dezelfde x.

Als je de waarde van die x niet hoeft te wijzigen, dan zou je hem ook mee kunnen geven als argument zonder die wrapper erom heen.

  • Mithrandir
  • Registratie: Januari 2001
  • Laatst online: 20:21
Op zondag 14 juli 2002 16:40 schreef Alarmnummer het volgende:
Hmmzz.. dit is een probleem dat je met c/pascal op zou lossen mbv een call by reference ipv een call by value. Hiervoor heb je dus pointers nodig, en ik betwijfel of php deze heeft. Watje wel zou kunnen doen is die x wrappen in een nieuwe class, en deze meegeven aan je functies. Hierdoor kunnen alle functies beschikken over dezelfde x.

Als je de waarde van die x niet hoeft te wijzigen, dan zou je hem ook mee kunnen geven als argument zonder die wrapper erom heen.
Jij zegt dus: Maak een nieuwe class, douw daar die variabele in, en lees die dan uit in de andere functie.

Zit wat in, maar echt mooi is 't ook niet. Maar wel mooier dan het vorige. Danx! :)

Verbouwing


Verwijderd

Probeer dit eens:
PHP:
1
<?class Template {    var $_layout;/* functions */    function loadLayout() {  $_layout = "<blaat>";}    function printLayout() {   print($_layout); }}?>

Ik weet wel dat het kan, maar niet of dit zo werkt.

Volgens mij is het zo dat je die *gedeclareerde* variabele kan vullen, en dan ergens anders in je classe weer kan gebruiken.

Verwijderd

gewoon in de ene functie $this->variablenaam = "value";

in de andere echo $this->variablenaam

edit: ff stukje code:
--
PHP:
1
<?class Template{   function Assign ()   {      $this->var = "hoi";   }   function doehetnu ()   {     echo $this->var; // dit print 'hoi'   }}?>

Verwijderd

Op zondag 14 juli 2002 16:49 schreef Stoel het volgende:
gewoon in de ene functie $this->variablenaam = "value";

in de andere echo $this->variablenaam
Juist, zo was het, alleen wel declareren van te voren.

Verwijderd

Je moet toch ook $this->layout doen? Op die manier kan je die variabele in elke method van een class gebruiken.

Verwijderd

Op zondag 14 juli 2002 16:51 schreef NextGeneration het volgende:

[..]

Juist, zo was het, alleen wel declareren van te voren.
hoeft niet eens !! :D

Verwijderd

Op zondag 14 juli 2002 16:52 schreef Stoel het volgende:

[..]

hoeft niet eens !! :D
ok, ok, maar voor het nette (hij wilde toch een nette oplossing :P)

Verwijderd

Wel als je met error_reporting(E_ALL) werkt.

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Op zondag 14 juli 2002 16:44 schreef Mithrandir het volgende:

[..]

Jij zegt dus: Maak een nieuwe class, douw daar die variabele in, en lees die dan uit in de andere functie.

Zit wat in, maar echt mooi is 't ook niet.
Zo los ik het in ieder geval in java op :) En ik zie niet wat er nou zo lelijk aan is. Met c/pascal kan je pointers gebruiken, en met java doet je het zo.

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Volgens mij valt dit onder werken met classes in php, les 1...

Die $this-> doet het hem, dan spreek je een class-var aan, ipv een gewone var.

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Op zondag 14 juli 2002 18:28 schreef ACM het volgende:
Volgens mij valt dit onder werken met classes in php, les 1...

Die $this-> doet het hem, dan spreek je een class-var aan, ipv een gewone var.
Dan moet je er wel van uitgaan dat je ook echt een globale variable wilt. Je mag natuurlijk geen 'globale' variable gaan introduceren omdat 2 functies op die manier moet elkaar moeten communiceren.

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Op zondag 14 juli 2002 18:45 schreef Alarmnummer het volgende:
Dan moet je er wel van uitgaan dat je ook echt een globale variable wilt. Je mag natuurlijk geen 'globale' variable gaan introduceren omdat 2 functies op die manier moet elkaar moeten communiceren.
Dit vind ik geen globale variabele...

En anders is er nog de variant:
code:
1
2
3
4
5
Aanroepende code:
$class = new class();

$var = $class->loaddindes();
$class->verwerk($var);

Andere varianten zijn er volgens mij niet echt bruikbaar voor of zijn wel terug te leiden op deze of de vorige die ik noemde?
(ja, met echt een global call is er nog...)

  • dusty
  • Registratie: Mei 2000
  • Laatst online: 21-02 00:06

dusty

Celebrate Life!

nooit eigen variabelen met _ starten, zijn in principe gereserveerd voor PHP. doe je het toch kan je in de toekomst er problemen mee krijgen.

Back In Black!
"Je moet haar alleen aan de ketting leggen" - MueR


  • eamelink
  • Registratie: Juni 2001
  • Niet online

eamelink

Droptikkels

Op zondag 14 juli 2002 16:40 schreef Alarmnummer het volgende:
Hmmzz.. dit is een probleem dat je met c/pascal op zou lossen mbv een call by reference ipv een call by value.
Speciaal voor jou een cbr ;):
PHP:
1
<?$a = "Hoi!";function ffProberen($val){        $val = "Hallo!";}ffProberen(&amp;$a);print $a;?>  ?>

  • Mithrandir
  • Registratie: Januari 2001
  • Laatst online: 20:21
het is me gelukt... Hier de hele code.
PHP:
1
<?/*********************************************** Script Timer Okke Formsma (Mithrandir) 2002 **************************************************USE**$timer->start('name');//put your code hereprint($timer->stop('name'));**********************************************/class timer{    var $tijd, $naam, $tijdNu, $tijdVerschil;        function start($naam)    {    $this->tijd[$naam] = explode(' ',microtime());    $this->tijd[$naam] = $this->tijd[$naam][0] + $this->tijd[$naam][1];    }        function stop($naam)    {    $this->tijdNu = explode(' ',microtime());    $this->tijdNu = $this->tijdNu[0] + $this->tijdNu[1];    $this->tijdVerschil = $this->tijdNu - $this->tijd[$naam];    return $this->tijdVerschil;    }}?>

/edit: IK HAAT TOPIX! (vooral dat 'ie de PHP code vernaggeld als je 'm wilt bewerken :(

Verbouwing


  • eamelink
  • Registratie: Juni 2001
  • Niet online

eamelink

Droptikkels

En werkt dit? Ik vind het maar een vaag zooitje!

$this->$this->naam <- Leg uit!

En je gebruikt allemaal members die niet eens bestaan :).

  • Mithrandir
  • Registratie: Januari 2001
  • Laatst online: 20:21
Op zondag 14 juli 2002 21:00 schreef eamelink het volgende:
En werkt dit? Ik vind het maar een vaag zooitje!

$this->$this->naam <- Leg uit!

En je gebruikt allemaal members die niet eens bestaan :).
het werkt. Ennuh

$this->$this->naam werkt hetzelfde als $$naam. maw: als $naam blaat is, dan wordt er een nieuwe variabele $blaat aangemaakt :) Daarmee kun je dus meerdere counters tegelijk draaiend hebben. Ik kan het ook oplossen met een array, maar daar had ik geen zin in :)
En members die niet bestaan? Ja, ik moet ze eigenlijk wel declareren. Heb je gelijk in :)

Verbouwing


  • eamelink
  • Registratie: Juni 2001
  • Niet online

eamelink

Droptikkels

Op zondag 14 juli 2002 21:03 schreef Mithrandir het volgende:
$this->$this->naam werkt hetzelfde als $$naam. maw: als $naam blaat is, dan wordt er een nieuwe variabele $blaat aangemaakt :)
Aaah, op die fiets, helemaal niet aan gedacht :)
Daarmee kun je dus meerdere counters tegelijk draaiend hebben.
Maar het is natuurlijk zo lelijk als het maar kan. Je weet van te voren nog niet eens hoe je members gaan heten! Dan kán je je members niet eens declareren.

Het lijkt me toch beter om voor elke timer de class opnieuw te instantiëren. Dat is toch de bedoeling van oo werken, of niet? ;)
En members die niet bestaan? Ja, ik moet ze eigenlijk wel declareren. Heb je gelijk in :)
Straks gaan nieuwere versies van php nog zeuren over niet gedeclareerde members. Dan zou je die hele lap code moeten herschrijven ;)

  • Mithrandir
  • Registratie: Januari 2001
  • Laatst online: 20:21
Op zondag 14 juli 2002 21:07 schreef eamelink het volgende:

[..]

Aaah, op die fiets, helemaal niet aan gedacht :)
[..]

Maar het is natuurlijk zo lelijk als het maar kan. Je weet van te voren nog niet eens hoe je members gaan heten! Dan kán je je members niet eens declareren.

Het lijkt me toch beter om voor elke timer de class opnieuw te instantiëren. Dat is toch de bedoeling van oo werken, of niet? ;)
[..]
Ok, bekijk de code nu nog eens, en je zal er hopelijk nu weinig op aan te merken hebben :)

Hmm, dat over OO heb je gelijk in. Maar dit is sneller (kost minder parsetijd) :)

Verbouwing


  • eamelink
  • Registratie: Juni 2001
  • Niet online

eamelink

Droptikkels

$naam is geen member dus die hoef je niet te declareren.

Als je toch een class aan het maken bent die er meerdere kan meten, dan zou ik hem nog wat uitgebreider maken. De stop method hoeft bijvoorbeeld niet de waarde te retourneren.

Als je een stop method maakt die de verschiltijd opslaat van die ene timer, en een aparte getTime method die die waarde retourneert, lijkt mij dat handiger in gebruik. Je kan dan zo werken:
PHP:
1
<?$timer = new Timer();$timer->start('totaal');$timer->start('firstpart');// Doe stuff$timer->stop('firstpart');// Doe nog wat$timer->start('databasequeries');// Execute queries$timer->stop('databasequeries');// Doe het laatste$timer->stop('totaal');print 'Het eerste gedeelte duurde zolang:' . $timer->getTime('firstpart');print 'De queries duurden zo lang:' . $timer->getTime('databasequeries');print 'Totale executietijd:' . $timer->getTime('totaal');?>

Mooi he? Dan kan je de tijden pas later printen, en eerder stoppen :)

[laatste opmerking]
Je zou iets betere benamingen kunnen gebruiken.
$tijd -> $start_tijd
$tijdNu -> $eind_tijd
[/laatste opmerking]

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Op zondag 14 juli 2002 20:53 schreef eamelink het volgende:

[..]

Speciaal voor jou een cbr ;):
PHP:
1
<?$a = "Hoi!";function ffProberen($val){        $val = "Hallo!";}ffProberen(&amp;amp;amp;$a);print $a;?>  ?>
Alles is bij php call by reference? Wat eng zeg dat een andere functie je waardes kan verneuken.

[edit] Ik zie dat er een & teken voorstaat. Zelfde als by pascal het woord 'var' :) Dat waren nog eens tijden, toen hadden we zelf geneste functies. (Hoop ook ooit nog eens dat we dat weer terug krijgen in java of c#).

  • eamelink
  • Registratie: Juni 2001
  • Niet online

eamelink

Droptikkels

Nee, het detaai was dus die & ervoor, dan roep je hem bij referentie aan :)

edit:

Voor mensen die nu een & gaan zoeken:
Die & staat dus voor de variabele die je als argument meegeeft

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Op zondag 14 juli 2002 22:09 schreef Alarmnummer het volgende:
Alles is bij php call by reference? Wat eng zeg dat een andere functie je waardes kan verneuken.
Nee, juist niet.

Het is in sommige situaties zelfs vrij lastig om _wel_ call by reference te krijgen...
Maar door die onduidelijkheid wordt het er niet beter op.

Java is toch voornamelijk ook call by reference??

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Op zondag 14 juli 2002 22:11 schreef ACM het volgende:
Nee, juist niet.
Ik zag net dat er een & teken stond, dus niet alles is automatisch call by reference. Ik weet inderdaad niet helemaal wat ik moet zeggen op jouw antwoord. Gedeeltelijk ben ik het ermee eens, omdat je een object ook altijd call by reference meegeeft (adres word gecopieerd op de stack). In dat opzicht had je ook dat net zo goed kunnen doen bij primitieve types.

Maar een object kan ik makkelijker beschermen als ik hem aan een methode meegeef. Ik zou hem zelf in een beschermende proxy kunnen plaatsen. Dit zou met een primitief type veel lastiger gaan.

Daarom ben ik wel blij dat in java niet alles call by reference is.
Java is toch voornamelijk ook call by reference??
Yepz :) Maar zie verhaal hierboven

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Klopt, maar die scheiding bij java is iig duidelijk :)

In php is dit bijv mogelijk:
PHP:
1
<?class bla{  function blabla(&amp;$objectreference)  {    $object = $objectreference;    $object->methode(); // NIET by reference    $objectreference->methode(); // WEL by reference    $objectref = &amp;$objectreference;    $objectref->methode(); // Weer WEL by reference    }}?>

Wat dus absoluut niet duidelijk is en voor vrij veel bugs zorgt/kan zorgen, zeker omdat je niet altijd by reference mee _kan_ geven. Ben er al es tegen aan gelopen met een XML-parsertje, die wilde ik in een recursieve object structuur plaatsen (niet in DOM, een eigen structuur) maar dat kon ik alleen als ik hem achterstevoren parste/linkte (kwa boom) omdat ie anders de references misliep |:( .

In Zend-engine2 wordt het geloof ik net als in java.

  • Mithrandir
  • Registratie: Januari 2001
  • Laatst online: 20:21
Op zondag 14 juli 2002 21:27 schreef eamelink het volgende:
[..]
[laatste opmerking]
Je zou iets betere benamingen kunnen gebruiken.
$tijd -> $start_tijd
$tijdNu -> $eind_tijd
[/laatste opmerking]
Goed idee!

* Mithrandir gaat meteen bezig :)

En ik kan trouwens nooit goede namen voor mijn variabelen verzinnen, dus danx :+

/edit: KLAAR!

ok, hier is de gehele, vernieuwde code. Met nog extra parameters! :)
PHP:
1
<?/*********************************************** Script Timer Okke Formsma (Mithrandir) 2002 **************************************************USE**$timer->start('total');//put some code here$timer->start('number one');//put more code here$timer->stop('number one');//put even more code here$timer->start('number two');//put some ehm... fish? here$timer->stop('number two');$timer->stop('total');//And now... showtime!print("Number one took " . $timer->getTime('number one') . " seconds");print("Number two started on " . $timer->getTime('number two',1) . " seconds");print("Number two stopped on " . $timer->getTime('number two',2) . " seconds");print("Number two took " . $timer->getTime('number two',0) . " seconds");print("The total took " . $timer->getTime('total') . " seconds");//The parameter number on function getTime is optionally and can be used in this way://0 Returns the time that has passed between start and stop in seconds [default]//1 Returns the start time in seconds//2 Returns the stop time in seconds**********************************************/class timer{    var $tijdStart, $tijdStop, $tijdVerschil;        function start($naam)    {        $this->tijdStart[$naam] = explode(' ',microtime());        $this->tijdStart[$naam] = $this->tijdStart[$naam][0] + $this->tijdStart[$naam][1];    }        function stop($naam)    {        $this->tijdStop[$naam] = explode(' ',microtime());        $this->tijdStop[$naam] = $this->tijdStop[$naam][0] + $this->tijdStop[$naam][1];        $this->tijdVerschil[$naam] = $this->tijdStop[$naam] - $this->tijdStart[$naam];    }        function getTime($naam,$extra = '0')    {        return $this->tijdVerschil[$naam];        switch ($this->extra)        {            case 0:                return $this->tijdVerschil[$naam];            case 1:                return $this->tijdStart[$naam];                break;            case 2:                return $this->tijdStop[$naam];                break;        }    }}?>

/edit:
Ik wordt helemaal ziek van topix! Zie ik weer een klein foutje in 't USE geval, moet ik m'n code weer gaan copy'en enzo :( Nouja... Nog eventjes... :)

/edit 3:
Zooow, nu is de manual helemaal bijgewerkt.

Verbouwing


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Oei oei oei, hier moet wat uitleg komen ;) .

Java kent geen call-by-reference. Als je een waarde by reference meegeeft, betekent dit namelijk dat je het adres meegeeft van een lokale variabele. Deze variabele staat in het stack-frame van de methode die een methode aanroept.

Via call-by-reference kan een aangeroepen methode in de aanroepende methode een lokale variabele aanpassen. Voor een primitieve betekent dit het geven van een andere waarde. Voor een object betekent dit ook het geven van een andere waarde: een nieuwe pointer naar een object. Het is in Java niet mogelijk om in de aanroepende methode zo'n lokale variabele aan te passen en algemener is het uberhaupt niet mogelijk om wat dan ook uit het stack-frame van de aanroepende methode te halen.

Als je een object aan een methode meegeeft, wordt de pointer naar dit object gekopieerd en meegegeven aan de methode. Dit wordt in de 'volksmond' vaak uitgelegd als call-by-reference en op zich kan ik me daar wel een beetje in vinden: de aangeroepen methode krijgt een referentie naar hetzelfde object als de aanroepende methode.

Strikt gezien is dit echter geen call-by-reference. Talen die wel call-by-reference kennen (C, C++, C# bijvoorbeeld) staan het dus toe om een lokale variabele by-reference mee te geven en zo de aanroepende methode deze lokake variabele te laten aanpassen.

Het heeft dus niet zozeer met bescherming te maken, maar meer met de vraag of een aangeroepen methoden bij lokake variabelen van de aanroepende methode kan. Als dat zo is, zijn er in wezen geen verschillen tussen primitieven en objecten omdat in beide gevallen de lokale variabele een nieuwe waarde kan krijgen.
Java is toch voornamelijk ook call by reference??
Nee dus :) .

Het belangrijke punt zit hem in de algemene opvatting over het by-value meegeven van een pointer naar een object. Dit wordt vaak als by-reference ervaren. Het is dus niet zo dat Java geeft objecten dus de gelegenheid geeft om by-reference meegegeven te worden en primitieven niet: er is een duidelijk grens gesteld: geen toegang tot het stack-frame van de aanroepende methode.

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Op zondag 14 juli 2002 23:39 schreef mbravenboer het volgende:verhaal over call by reference.
Ik denk dat de meesten mensen ook in gedachten hadden dat een call by reference in java (dus adres meecopieren op de stack) niet de zo echt is een call by reference zoals pointer talen dat hebben, maar uiteindelijk toch wel als een call by reference overkomt. Je hebt aangeroepte methode tenslotte beschikken over objecten van de aanroepende methode.

  • Mithrandir
  • Registratie: Januari 2001
  • Laatst online: 20:21
* Mithrandir vraagt zich af waarom die mensen altijd zo'n moelijke discussie gaan houden in zijn topics in PW

Eej, toen ik ff naar mijn username zocht, zag ik een naaper: "Mithrandir_XP" :( Hoe durft 'ie, mijn naam en dan eXPired erachter zetten! :(

Verbouwing


  • D2k
  • Registratie: Januari 2001
  • Laatst online: 31-08 10:19

D2k

Op zondag 14 juli 2002 23:54 schreef Mithrandir het volgende:
* Mithrandir vraagt zich af waarom die mensen altijd zo'n moelijke discussie gaan houden in zijn topics
om je meer te leren :?

Doet iets met Cloud (MS/IBM)


  • Mithrandir
  • Registratie: Januari 2001
  • Laatst online: 20:21
Op zondag 14 juli 2002 23:55 schreef D2k het volgende:

[..]

om je meer te leren :?
Jou got a point there ;)
Maar ik snap d'r bijna niets van :'(... Vakliteratuur is moeilijk :P

Verbouwing


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Op zondag 14 juli 2002 23:55 schreef D2k het volgende:

[..]

om je meer te leren :?
Omdat we echte nerds zijn ;)

  • D2k
  • Registratie: Januari 2001
  • Laatst online: 31-08 10:19

D2k

Op zondag 14 juli 2002 23:57 schreef Alarmnummer het volgende:

[..]

Omdat we echte nerds zijn ;)
speak for yourself ;)
maar dus om je meer inzicht in de materie te geven

Doet iets met Cloud (MS/IBM)


  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Op zondag 14 juli 2002 23:52 schreef Alarmnummer het volgende:
Ik denk dat de meesten mensen ook in gedachten hadden dat een call by reference in java (dus adres meecopieren op de stack) niet de zo echt is een call by reference zoals pointer talen dat hebben, maar uiteindelijk toch wel als een call by reference overkomt. Je hebt aangeroepte methode tenslotte beschikken over objecten van de aanroepende methode.
Yups en het hangt nog van je definitie van call by reference af ook denk ik.
Want in java komt er wel op een of andere manier een referentie naar hetzelfde object van de ene in de andere methode.

Of dat nou via pointers loopt of door de taal verborgen met dezelfde adressen in de stack...
Maakt dat zoveel uit voor de 'call by reference' definitie?

Want wat doe je nou eigenlijk als je in C een methode aanroep _met_ een pointer doet?
Dan kopieer ie het adres van die pointer toch naar die methode toe? ;)
Precies wat jij (mbravenboer) zegt dat java doet...

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Je zou ook de pointer van de pointer kunnen meegeven :P

*weet meteen weer waarom hij zo blij was met java*

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 00:57

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op zondag 14 juli 2002 22:09 schreef Alarmnummer het volgende:

Dat waren nog eens tijden, toen hadden we zelf geneste functies. (Hoop ook ooit nog eens dat we dat weer terug krijgen in java of c#).
nee asjeblieft niet, zorgt alleen maar voor problemen. Dat je bijvoorbeeld een pointer van een geneste functie doorgeeft aan een andere functie, die vervolgens de geneste functie weer aanroept. Op zich niet erg, maar als die geneste functie bij de variabelen van z'n parent probeert te komen gaat het gigantisch fout omdat de stack frame niet klopt :P (been there, done that :+)

Maar ze zijn soms wel handig ja, dat geef ik toe ;)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
ACM: Maakt dat zoveel uit voor de 'call by reference' definitie?
Het hele punt draait om het nemen van het adres van een lokake variabele. Een adres op de stack dus. In een taal als C is het mogelijk om hier flink mee aan te klooien: de programmeur kan zelf het adres van lokale variabelen nemen, hij kan er mee rekenen en de volgorde van addressen wordt zelfs gebruikt voor arrays.

Een tussenweg tussen deze volledige vrijheid met addressen en het volledig verborgen houden van addressen is call-by-reference. Bij het gebruik van call-by-reference manipuleert de programmeur niet zelf met addressen en hoeft de taal hiervoor dus ook geen functionaliteit te bevatten. Als een lokake variabele echter by-reference wordt meegegeven als argument aan een methode, dan wordt het adres van de lokale variabele genomen en meegegeven aan deze methode. Dit adres is een adres in het stack-frame (activation record) van de aanroepende methode (callee).

Voor als je leuke boeken hebt:

Modern Compiler Implementation in Java/C/ML - sectie 6.1 - Parameter Passing.

Compilers, Principles, Techniques and Tools - sectie 7.5 - Parameters Passing. De sectie hiervoor (Access to nonlocal names) is ook zeer boeiend.

Wat jullie (en velen anderen) dus ook graag call-by-reference noemen is simpelweg het meegeven van een pointer naar een locatie op de heap, zonder heel het item op de heap te gaan kopieren. Dit kan je prima goed als by-reference ervaren, maar het is wel belangrijk om het onderscheid te maken met call-by-reference.

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
.oisyn: [geneste functies] nee asjeblieft niet, zorgt alleen maar voor problemen. Dat je bijvoorbeeld een pointer van een geneste functie doorgeeft aan een andere functie, die vervolgens de geneste functie weer aanroept.
Er zijn inderdaad veel problemen mee, maar ik vermoed dat Alarmnummer geen functie pointers wil introduceren in Java :+ .

Op zich is er helemaal niets mis met geneste functies met lexical scope (wat betekent dat ze bij lokale variabelen van de omringende functies kunnen komen). Zodra je echter ook functie-pointers hebt en deze op kunt leveren vanuit een methode kan je flink de pineut worden.

De combinatie van deze twee features is zoals .oisyn aangaf een groot probleem: er kunnen lokale variabele van de omringende methode nodig zijn, terwijl het stack-frame van deze omringende methode wellicht allang is opgeruimd.

Je taal is dan strikt genomen alleen nog correct bezig als stack-frames op de heap gealloceerd kunnen worden indien nodig.

Omdat die oplossing nog niet zo triviaal is, kiezen veel talen juist voor 1 van deze twee features (of geneste functies, of de mogelijkheid om functie-pointers op te leveren als resultaat).

Vrijwel alle functionele talen kennen echter wel beide features en bieden daarom hogere orde functies. In deze talen kan het nodig zijn om het stack-frame/activation record van een methode op de heap te plaatsen voor later gebruik.

Weer even voor de mensen die leuke boeken bezitten:

Modern Compiler Implementation in C/Java/ML: Hoofdstuk 6: Activation Records, Introduction - Higher-Order Functions.

In het Aho boek kon ik zo snel geen duidelijke sectie vinden die precies hierover gaat. De Introduction in het vorige boek is echter erg duidelijk.

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Mithrandir: Maar ik snap d'r bijna niets van :'(...
Hum ja, normaal gesproken probeer ik altijd zo toegankelijk mogelijk alles uit te leggen, zodat ook mensen die nog flink aan het leren zijn het goed kunnen begrijpen. Helaas heb je voor dit onderwerp echter een beetje veel basiskennis nodig en dat heeft tot gevolg dat ik dan echt hele pagina's uitleg moet gaan zitten tikken :7 . Ik heb geen problemen met een lange post, maar zodra ik het idee heb aan een boek te beginnen kan ik me toch beter maar een beetje beperken :+ .

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment

Pagina: 1