PDA

Volledige versie bekijken : Hoe static property opvragen m.b.v. parameter in static function


Laiverd
%Europe/Berlin %895 %2006, 22:29
Stel ik heb dit

class Myclass {
private static var a:Array = ["plip","plop","plup"];
private static var b:Array = ["blob","blub","b;ab"];
public static function showVar(v:Array){
trace(v);
}

}

Als ik de waarden van array a wil opvragen met
Myclass.showVar(a);dan werkt dit niet, en krijg ik 'undefined' terug. Vraag is dus hoe ik in een static function een parameter kan gebruiken om een static property op te vragen. Ik kan natuurlijk per var een aparte method aanmaken, maar dat lijkt me wat idiote overkill. Heb verschillende dingen geprobeerd, maar ik kom er niet uit.

Tnx. voor de input.
John

marcvz
%Europe/Berlin %898 %2006, 22:33
Waarom maak je die vars private?
Is het niet net zo handig om gewoon public static vars te maken en dan aanroepen met Myclass.staticVarName?

Hoef je geen eens methods te maken om ze uit te lezen.

Laiverd
%Europe/Berlin %899 %2006, 22:34
Ik snap dat het op jouw manier kan, maar wil dus weten waarom het bovenstaande niet werkt, en hoe ik het wel werkend kan krijgen ;)

John

Emveedee
%Europe/Berlin %902 %2006, 22:39
Ik weet het niet helemaal zeker,
ben niet zo bekend met classes,
dus ik kan fout zitten ;)

Maar het is toch zo dat een private var niet opgeroepen of gewijzigd kan worden,
behalve in de class zelf?
Dus dan lijkt t me vrij logisch dat je dat ook niet via een functie zoals die kan doen.

Mzl

marcvz
%Europe/Berlin %905 %2006, 22:43
Kan wel, static vars zijn vars op de class zelf. Niet op de instances van de class.
Zo kun je bv een teller bijhouden om te kijken hoeveel instances van je class je al aangemaakt hebt.

Laiverd
%Europe/Berlin %905 %2006, 22:43
Dat klopt op zich wel, maar dan zou ik een foutmelding moeten krijgen en die krijg ik niet. Bovendien kun je vanuit een class en private var wel opvragen via een method; alleen niet direct met de var naam.

Even voor de duidelijkheid; het volgende werkt wel:
public static function showVar(){
trace(a);
}maar ik wil dus die a via een parameter door kunnen geven

John

Dauntless
%Europe/Berlin %908 %2006, 22:47
Waarom maak je die vars private?
Het is een goede gewoonte om alle variabelen private te houden.

Maar het is toch zo dat een private var niet opgeroepen of gewijzigd kan worden,
behalve in de class zelf?
Dus dan lijkt t me vrij logisch dat je dat ook niet via een functie zoals die kan doen.
De functie behoort toch tot de classe? Het zou juist onlogisch zijn als hij er GEEN toegang tot had.


Het probleem is dus: Je geeft aan de functie showVar een variabele mee. Die variabele is alleen beschikbaar binnen de class (private) en via de classnaam (MyClass.a).
De constructie die je hier hebt is dus inderdaad niet mogelijk. Je wil een private variabele gebruiken buiten een classe en dan ook nog via een niet-static manier.

Ik zal even zoeken naar een vergelijkbaar voorbeeld in AS 1.0... (Wat niet echt simpel is... ik zit hier al even te denken :p)

theFlashWizard
%Europe/Berlin %909 %2006, 22:49
a zit toch in de class?
dan dacht ik dat je die zo moest opvragen:
Myclass.a;
in jou script:
Myclass.showVar(Myclass.a);
Alleen gaat dat in jou geval niet lukken omdat je a als private hebt opgeven.

marcvz
%Europe/Berlin %909 %2006, 22:49
Het probleem zit hem denk in het path naar het object toe.
Net als je in een fla met eval en path[] werkt om naar een object te verwijzen.
Want als je ipv trace(v) gewoon trace(a) pakt werkt het wel.

Oplossing zou dus zijn om een switch te maken met voor de verschillende waardes van 'v'. Echt netjes is dit niet, maar weet zo snel geen andere oplossing.

marcvz
%Europe/Berlin %911 %2006, 22:52
@Dauntless

Het is een goede gewoonte om alle variabelen private te houden.


True, en dan aanpassen via get en set methods.

Die andere quote van je, kwam niet bij mij vandaan. Ik gaf juist aan dan het wel kon ;)

Laiverd
%Europe/Berlin %912 %2006, 22:53
No offense FW ;), maar die suggestie is hierboven ook al gedaan en ik snap echt dat het zo ook kan. Maar zoals ik het heb geleerd is het beter om properties private te houden (zoals Dauntless ook zegt) en ze evt. toegankelijk te maken via een getter functie. Hoe dan ook: ik ben dus op zoek naar een mogelijkheid om via een getter-achtige functie d.m.v. een parameter toegang te krijgen.

Overigens heb ik me ook al suf gezocht op het web, maar het lijkt wel of niemand dit probleem ooit zo is tegen gekomen. Kan natuurlijk ook zijn dat ik iets heel onlogisch wil, maar dan wil ik graag weten
a. waarom het onlogisch is en
b. waarom het dan niet kan ;) > ik begrijp dus ook niet helemaal wat Dauntless daarover zegt.

John

Dauntless
%Europe/Berlin %913 %2006, 22:55
Altijd leuk als je reactie genegeerd wordt :D.

Vergelijk het met dit:

//nieuw object
var ob:Object = new Object();

//nieuwe property
ob.a = "hallo";

//nieuwe method
ob.traceVar(myVar)
{
trace(myVar);
}
/*
Dus, als je ob.traceVar(a) doet dan zal je undefined krijgen. 'a' bestaat immers enkel als een variabele van het object 'ob'.
*/
ob.traceVar(a); //undefined

//maar 'a' bestaat dus wel als een propertie van ob:
ob.traceVar(ob.a); // hallo

Begrijp je ?

Laiverd
%Europe/Berlin %915 %2006, 22:58
@DL Ja die snap ik. Maar dan zou dit dus wel moeten werken en dat doet het ook niet:

public static function showVar(v:Array){
trace(Myclass[v]);
}John
P.s. Soms ben ik wel een moeilijke leerling ;)

Dauntless
%Europe/Berlin %916 %2006, 22:59
Idee!

Vergelijk het met dit:

function a()
{
return "oy";
}

var ob:Object = new Object();
ob.traceVar = function(myVar:String)
{
trace(myVar);
}

ob.traceVar(a());

Hieruit kan je afleiden dat ee parameter eerst wordt geevalueerd vooralleer hij naar de functie gezonden wordt. (Anders zou je dus een error krijgen omdat je een functie als parameter geeft ipv een string).

Dus. Bij jou: Je gebruikt 'a'. die variabele bestaat niet buiten de classe en dus wordt deze geevalueerd naar 'undefined'. Die waarde (undefined) wordt dan naar je classe gegeven en getraced.

Duidelijk ? :p

//EDIT
Als je hem zo oproept wel:
MyClass.showVar("a");
Je weet toch hoe 'associative array referencing' werkt? Dat is wat je hier doet ...

Laiverd
%Europe/Berlin %919 %2006, 23:03
Hmm, ik snap geloof ik wel wat je zegt ... en dat betekent dan dus dat de enige manier om access te krijgen tot die static properties, de manier van FlashWizard en Marcvz is??? Toch vreemd als overal wordt gepropageerd dat het niet proper OOP is om properties direct toegankelijk te maken.

John

Dauntless
%Europe/Berlin %920 %2006, 23:05
class Myclass {
private static var a:Array = ["plip","plop","plup"];
private static var b:Array = ["blob","blub","b;ab"];
public static function getA():Array
{
return a;
}

}
Zo doe ik het... (Heb nog niet echt met getter/setters gewerkt, maar komt op hetzelfde neer).
En zo doet MM het eigenlijk ook: TextField.getFontsList(); is eigenlijk hetzelfde als wat je hier doet :).

Laiverd
%Europe/Berlin %922 %2006, 23:08
//EDIT
Als je hem zo oproept wel:
MyClass.showVar("a");
Je weet toch hoe 'associative array referencing' werkt? Dat is wat je hier doet ...Eerlijk gezegd: ... ik weet niet waar je het over hebt :D, en die code geeft een Type mismatch foutmelding. Ergens info te vinden over 'associative array referencing'? (Misschien is het trouwens wel iets dat ik wel regelmatig gebruik, maar waarvan ik gewoon niet weet dat het zo heet )


//EDIT Lees net je laatste post. Is inderdaad wel een oplossing die ik ook had bedacht, maar waarvan ik dacht, dan moet slimmer kunnen ;) Op deze manier moet je voor iedere property dus een method aanmaken. (aan de andere kant; dat doe je met getters eigenlijk ook).

John

marcvz
%Europe/Berlin %923 %2006, 23:10
Wat Dauntless daarmee bedoelde:
Je moet dus van je v:Array even v:String maken.


class Myclass {
private static var a:Array = ["plip","plop","plup"];
private static var b:Array = ["blob","blub","b;ab"];
public static function showVar(v:String){
trace(Myclass[v]);
}

}

MyClass.showVar("a");

Dauntless
%Europe/Berlin %924 %2006, 23:10
Je moet dan natuurlijk wel ':Array' naar ':String' veranderen.

En dit is associative array referencing (ik heb het waarschijnlijk wel fout geschreven :# ):

var naam:String = "Dauntless";
var theVar:String = "naam";
trace(this[theVar]);

Laiverd
%Europe/Berlin %924 %2006, 23:11
Okay mensen: hartstikke bedankt voor het meedenken. Ik laat het allemaal eens even bezinken ;) Het is me wel iets duidelijker geworden.

John

Dauntless
%Europe/Berlin %925 %2006, 23:13
Graag gedaan :). Post maar als het toch nog niet duidelijk is :p. (Don't be ashamed !:p)

Laiverd
%Europe/Berlin %932 %2006, 23:22
Heb geloof ik wel een oplossing gevonden, waardoor ik toch met 1 en dezelfde methode meerdere props kan benaderen:

class Myclass
{
private static var a : Array = ["plip", "plop", "plup"];
private static var b : Array = ["blob", "blub", "b;ab"];
public static function showVar (v)
{
switch (v)
{
case "a" :
getA ()
break;
case "b" :
getB ();
break;
default :
trace ("v is undefined")
}
}
private static function getA ()
{
trace (a);
}
private static function getB ()
{
trace (b);
}
}Nu kan ik wel dit doen:
Myclass.showVar("a");en heb ik maar 1 public method nodig.

Dauntless
%Europe/Berlin %934 %2006, 23:25
Maar dat is wel ongelofelijk statisch (lol, dubbelzinigheid :p).

Maaruhm... Wat ben je nog van plan met 'a', 'b' en 'c' ? (Dit is waarschijnlijk gewoon een voorbeeld, maar toch... Kan je de situatie uitleggen ?)

Laiverd
%Europe/Berlin %937 %2006, 23:29
Ben aan het kijken of ik de Date class niet kan uitbreiden met wat handigheidjes, zoals bv. teruggeven van een maand-naam i.p.v. een nummer, en dat je dat dan ook nog kunt doen in de taal van je besturingssysteem (of een zelf aangegeven taal). Die class zou dan een aantal arrays bevatten (ja static ;) ) met de namen van de maanden in verschillende talen. Verder nog niet heel uitgebreid over nagedacht, maar kwam direct dit al tegen.

John

marcvz
%Europe/Berlin %937 %2006, 23:30
OMG Laiverd. Dat zei ik in mijn 2e post al. Dat je een switch kon gebruiken, maar dat dat niet echt een nette oplossing is.

Als je toch met String gaat werken. Kun je toch ook met de path[] method werken?

Nogmaals zo dus:

Class:

class Myclass {
private static var a:Array = ["plip","plop","plup"];
private static var b:Array = ["blob","blub","b;ab"];
public static function showVar(v:String){
trace(Myclass[v]);
}

}

fla:

Myclass.showVar("a")

Dauntless
%Europe/Berlin %939 %2006, 23:32
De Date class heeft maar 1 static method (getUCD). Waarom wil je een methode voor 'getMonthName' (bv) statisch maken? Dat is toch verschillend voor elk date object ?

Laiverd
%Europe/Berlin %940 %2006, 23:34
Ik weet het; ben er geloof ik niet helemaal bij. Sorry daarvoor. Maar je codevariant had ik zo al geprobeerd en die blijft bij mij echt 'undefined' geven.

//EDIT: vergeet het maar; ik moet gaan slapen; werkt perfect. Tnx mrcvz

John

Dauntless
%Europe/Berlin %941 %2006, 23:36
Dit geeft undefined?
class Myclass {
private static var a:Array = ["plip","plop","plup"];
private static var b:Array = ["blob","blub","b;ab"];
public static function showVar(v:String){
trace(Myclass[v]);
}

}

//oproepen met
Myclass.showVar("a");


Bij mij werkt dit gewoon ...

Laiverd
%Europe/Berlin %942 %2006, 23:37
Zal de volgende keer eens wat eerder op de avond gaan posten :D

Dauntless
%Europe/Berlin %943 %2006, 23:38
Lol :p.

Dus alles opgelost ? Als je nog vragen hebt, post ze maar :).

Laiverd
%Europe/Berlin %945 %2006, 23:41
Tnx. Ik kan voorlopig wel weer even (of wat langer ;) ) vooruit.

John

Roenes
%Europe/Berlin %966 %2006, 00:11
class Myclass {
private static var a:Array = ["plip","plop","plup"];
private static var b:Array = ["blob","blub","b;ab"];
public static function showVar(v:String){
trace(Myclass[v]);
}

}

//oproepen met
Myclass.showVar("a");Deze variant is meerdere malen geopperd maar ondanks dat dit werkt is het een waardeloze variant (OOP gezien). Je moet een string meegeven die overeenkomt met de naam van een private property. Denk daar eens over na! Een private property maak je private om em af te schermen van de buitenwereld. Maar je verwacht wel dat je aan je methode de naam meegeeft van een property die je in eerste instantie niet aan de buitenwereld wil blootstellen. Ondanks dat het werkt slaat het eigenlijk nergens op (OOP gezien dan ;)) :)

switch en dergelijke kan op zich ook wel, maar dan hou je een soort van gelijk probleem. Je moet dan een bepaalde waarde meegeven die overeen komt met je private vars. Wederom niet ideaal. :)

Volgens mij is het nogsteeds het best om voor die private var's mooie getters en setters te maken. Maar laat niet code van buiten afhangen van de naam van een private prop. Ze zijn immers niet voor niets private gemaakt. Met getters en setters heb je iets meer vrijheid aangezien je de private var kan hernoemen zonder dat je de getters/setters perse moet hernoemen (al zal je code dan niet echt duidelijk blijven, maar het is in ieder geval niet verplicht :)).
Zie het voordeel al als je bijvoorbeeld een kleine letter van je private prop aanpast in een hoofdletter. Je getter en setter methode hoef je niet te hernoemen (wel herschrijven intern) maar de eerder genoemde methode met de naam meegeven werkt niet meer doordat ze niet dezelfde case meer hebben :)

Jimbooo
%Europe/Berlin %397 %2006, 10:32
Ik ben het helemaal met Roenes eens. Hoewel het zoeken naar een creatieve oplossing natuurlijk erg interessant is, is het natuurlijk volledig in strijd met OOP. Aangezien ik (voordat ik met Actionscript begon) alleen maar OOP geprogrammeerd heb, zat ik tijdens het lezen van de posts mezelf al af te vragen wat nu het hele nut van deze discussie is. Volgens de grondbeginselen van OOP worden private vars gewoon via getters en setters geinstantieerd/opgevraagd.

Wat je nu dus eigenlijk doet is: Object georienteerd programmeren, maar dit vervolgens weer gaan mixen met "rechtoe rechtaan" programmeren.

Laiverd
%Europe/Berlin %473 %2006, 12:22
Food for more thought. Heel goed: tnx jongens. Uiteindelijk zal het wel iets met getters worden; dit was maar een begin en iets waar ik al snel tegenaan liep ;)

John

Roenes
%Europe/Berlin %770 %2006, 19:29
Ik moet wel zeggen dat ik het gisteravond wel een leuke discussie vond om te lezen! Dus ondanks dat het geheel tegen OOP in gaat was het wel interessant. Geslaagde discussie wat mij betreft :)

Laiverd
%Europe/Berlin %783 %2006, 19:48
Dat vond ik nou ook. Moeten we vaker doen ;)

Dauntless
%Europe/Berlin %861 %2006, 21:39
Idd, wat heb je er aan als je gewoon zegt: 'Dat gaat tegen de OOP denkwijze in, stop er mee en begin met iets anders...' . Dan zijn zo'n discussies veel leuker :D.