Pomoć - Pretraga - Članovi - Kalendar
Puna verzija: [info] O FP8,9 AS2/3 Garbage Collector-u
Dizajn Zona > Tehnike > Flash
syndrome
1.
Kao sto rekoh u opisu, jako interesantni aspekti GC-a o kojima nisam razmisljao ranije.
Zasto nisam razmisljao? Zato sto su uzimane zdravo za gotovo i mogu se pronaci i u Flash helpu.

Kao npr. ovaj primer koji je covek okacio u ovom clanku dole.
Svako ko je radio sa XML-om, bar jednom je napisao ovakav kod.

CODE
my_mc.onPress = function()
{
    var my_xml = new XML();
    my_xml.ignoreWhite = true;
    my_xml.onLoad = function(success)
    {
       trace("success!, parse this.");
    };
    my_xml.load("some.xml");
}

Medjutim, gde je problem ovde?
Problem je u tome sto je poziv asinhron i sto je my_xml implicitna lokalna varijabla. (edit: nije implicitna, ali je lokalna)
Ona zaokupira memoriju, dobije referencu na novokreirani XML objekat, zatim se preko nje poziva load metoda i onda se funkcija onPress zavrsi i, logicno, my_xml varijabla umre, jer je bila lokalna.

Medjutim, GC kasni, i zbog toga ova varijabla ne umire. Pre nego sto je GC zakaci, XML stize i poziva se onLoad metoda preko reference koja vise nije validna.
Prevarismo GC, a i dobili smo XML, zar ne? smile.gif

Nije bas legalan trik, tj. vrlo je prljav, ali kao sto rekoh, svi su prihvatili ovo zdravo za gotovo.
Mozda ne bi bilo lose zaobilaziti ovo u buducnosti.

Uglavnom, izgleda da to radi tako i u AS3, ali ako neko pretera sa kolicinom podataka, doci ce GC (koji je osetljiv na velicinu i kolicinu podataka) i cao.

Clanak.

2.
Btw, kad smo vec kod Garbage Collectora, evo jednog zanimljivog benchmarka iz 2006.

Iz nekog razloga, ovaj novi GC, za koji je onaj Uro Tinic jos 2005 rekao da je masterpiece, ne ocisti sve.
Zasto je to tako, beats me, ali sam i sam pravio neke testove (2 godine kasnije) u Playeru 9 i nisam zadovoljan.

3.
Btw, jos jedna stvar koju je neko pitao na tom (zadnjelinkovanom) blogu. Interesantno pitanje koje i mene muci:
CITAT (Marcelo)
While porting some components so they can take advantage of the new methods of FP8, i saw the following:
If you enable the redraw regions, and use scrollRect somewhere, you will see that the player redraws the complete clipped
movieclip, instead of the clipped region only.

What are the benefits if the player has to redraw the whole screen? (assuming you clipped content has the same size as your
stage, and of course the clipped area is smaller).
CITAT (Uro Tinic)
Marcelo: This is a known bug we haven't been able to fix in this release. It has now become much more visibile since you can display redraw regions. I hope we can tackle this next time around.
To je bilo 2005. Hmm...
Element9
Da ne ostane tema bez i jednog odgovora. smile.gif

To je sasvim normalno. Mislim, ako se koristi lokalna promenljiva naravno da ce da nestane na kraju funkcije, ali stvarno se takve stvari zaborave.

U AS 3.0 nekako prirodno dodje da napises sebi neku XMLLoader klasu koja ti vraca xml preko eventa. Tako reference nema sanse da umre.
syndrome
Znam da je normalno, ali tema poput ove je upucena upravo starim vukovima u Flashu. Zato me ne cudi sto se javio Javash smile.gif

Ono sto je interesantno, u slucaju koji sam naveo gore, je sledeca stvar:
my_xml umre kada onPress sidje sa stacka, jer je vek te varijable bio privremen. Medjutim, pre nego sto je ugasena, njoj je dodeljena referenca na objekat, zatim je jednoj metodi (callback funkciji) tog objekta dodeljena anonimna funkcija, i konacno, druga metoda je pozvana. Flash player preko sasvim drugog threada (asinhrono) sada pokusava da ucita XML i u trenutku kada uspe u tome, poziva callback funkciju nad objektom cija referenca mu je poznata, ali(!) nista vise ne pokazuje na taj objekat, jer my_xml vise ne postoji. Reference counter ovog objekta je 0, i postao je plen za GC. Tehnicki, XML objekat ne postoji, ali GC nije stigao da ga ukloni, pre nego sto je ovaj zavrsio posao.

Hehe, ne znam zasto, ali meni je strasno zabavno kad vidim da je ovakva jedna katastrofalna zloupotreba pronasla put do helpa, samo zato sto u praksi radi 100% (u jednostavnim slucajevima, kao sto je ovaj).

Taj lik koji je otkrio ovo, imao je stotinak ovakvih lokalnih varijabli (budala) i ocigledno je skrenuo paznju GC-a kao Neo kad skoci medj' letece robote.

Anyway, tehnicki bi bilo najispravnije uraditi ovo unutar klase koja ima privatnu varijablu my_xml, koja se koristi u odgovarajucoj metodi, po potrebi. Nije neka velika razlika u odnosu na ovo, samo se doda deklaracija varijable izvan metode, a lokalni var se baca u djubre, ostavi se samo definicija.

Ali cak iako znam za to (vise zato sto imam neki los feeling u stomaku nego zato sto sam ikada razmisljao sta nije u redu s tim), kad sam ovo procitao, pregledao sam ovaj veliki projekat na kojem trenutno radim i uhvatio sam sam sebe na par mesta (od jedno 7-8), kako pravim identicnu gresku.

Ostaje na kraju ta dilema: menjati nesto sto radi i priznati programersku sujetu, ili ostaviti tako kako jeste i priznati gresku koja je, moram priznati, pocetnicka?
MrSteel
zanimljiva je tema, ali Flash i vrhunski softverski inzenjering ne ide *ne u smislu pisanja samog programa i njegove koncepcije nego finesa koje bi mogle da se izvedu, jer ipak radis na kraju za player koji moze tacno to i to, tako da i kada bi napravio svoj kompajler ne bi mogao da odradis recimo svoj GC
krpiti ono sto ne radi to je parola, AS3 je itekako poboljsao stvari
a pitanje ispravljati ili ne, definitvno vredi ispravljati ako sumnjas da ce ti nekad to potrositi vise vremena u radu nego da sada ispravis kada je sve safe
syndrome
CITAT
tako da i kada bi napravio svoj kompajler ne bi mogao da odradis recimo svoj GC

Da, ogranicenja postoje, ali cak ni u Javi ne mozes da napravis low-level GC, samim tim nailazis na isto ogranicenje koje ti namece postojanje same virtuelne masine.
To znaci da to nije ono sto cini programski jezik mocnim, a skripting jezik siromasnim. U stvari siguran sam da vecina visokih jezika ne moze samu sebe da organizuje na low-level nivou, cime se ActionScript ni po cemu ne razlikuje od njih.
Drugim recima, odgovornost programera da vodi racuna o behind the scene elementima je univerzalna, koristio on ActionScript, C# ili Javu.
Sto se tice AS2, slazem se da se sve svodilo na krpljenje, ali kao sto rekoh, gorenavedena stvar radi i u ASu3 (doduse, nisam licno pokusao), mada nisam video takav primer u helpu. Potrudicu se da saznam.
MrSteel
mogucnosti cine jedan programski jezik mocnim a drugi ne
mada nije bitna tu moc koliko same te mogucnosti
ako se radi o tim finesama onda se ne moze actionscript stavljati uopste u red sa c++ i sl.
javu nisam imao na umu wink.gif java je puna mogucnosti, rispekt
actionscript ima neke druge svoje prednosti rispekt
sto se tice odgovornosti, mora da je ima, negde je ona veca negde manja, bas u zavisnoti od mogucnosti
ali sto su one vece, to program moze biti bolji brzi i sl.

zato sam i izbegavao uospte da pricam o ovim elementima u Flashu
ne mogu da ga posmatram kao mashinu za full metal jacket programing
ti neki propusti i nisu tako veliki, a dok to nije fatal error sve je ok, mali skok i kazes hop
to je lepsa strana svega ovoga
the
interesantna GC priča ali...
pošto za razliku od vas xml koristim do kraja (ne koristim ga da samo pretabam podatke u niz), meni je pravilo da xml svakako bude vezan za odgovarajući objekat, pa je samim tim i navedeni primer bespredmetan.
syndrome
CITAT (the @ Nov 2 2007, 14:57) *
pošto za razliku od vas xml koristim do kraja (ne koristim ga da samo pretabam podatke u niz), meni je pravilo da xml svakako bude vezan za odgovarajući objekat, pa je samim tim i navedeni primer bespredmetan.
Otkud to?
Ako i koristim niz, on je samo intermediate medij za sortiranje i slicno, pre nego sto te podatke i prikazem.
Nikad ne pretabavam XML u niz bez dobrog razloga.
Nisi valjda nekad sortirao podatke direktno u XMLu?

Ne znam zasto mislis da sam toliko disrespectful prema XMLu. Ako je to zbog ForXa, onda bi trebalo njime da se pozabavis i da vidis cemu sluzi. Evo i dobrog primera.

Uostalom, zaboravljas da ja nisam Flash programer. Imao sam ja svoje epizode u mnogim jezicima, samo je tesko pricati o necemu u cemu ne radis svakodnevno. U stvari, mnogo vaznije od svega toga je sto imam debelu OOP zaledjinu, kao i debelo iskustvo u aplikativnom softveru. Da nije bilo Flasha, radio bih iskljucivo u Javi, ali je pitanje da li bih se time bavio profesionalno -- uglavnom zbog toga sto sam bio poprilicno nesiguran u sebe i mlatio sam se sa pripremom, od koje se moglo ziveti.

Dug je to put, i jako komplikovana prica koja nema veze sa Flashom. Ne znam koliko je realno porediti moj stil programiranja sa klasicnim Flash fanboi stilom.
the
smile.gif
ma ok, samo, primer koji si dao je upravo za usputnu upotrebu xml-a.

btw, probao sam forx u konkretnom slučaju ali sam na kraju ipak odustao. ne sećam se više šta je na kraju bio fazon ali znam da smo gvozden i ja isprobavali nešto sa vraćanjem liste nodova po određenom kriterijumu / nije proradilo očekivano.
jasno je meni šta je forx i čemu služi, ali uglavnom nemam potrebe za njim jer meni u xml-u i treba šetnja kroz stablo. iščitavanje sadržaja base-olikih xml-ova je skroz druga priča...
syndrome
CITAT
nije proradilo očekivano
Sta to znaci?
Pronasli ste bag? Ne moze da uradi nesto sto vam je trebalo?
Ili niste procitali dokumentaciju?

Stvarno bih voleo da cujem sta nije u redu sa ForXom kako bih ga popravio/napravio da bude bolji.

Poslednja stvar na koju mi je MrSteel obratio paznju je implementirana u poslednjoj verziji.

Jako mi je vazno da znam sta ste to pokusali da uradite.

Sto se tice setnje kroz stablo, u pravu si -- ForX nije za setnju, uglavnom zato sto je to vec omoguceno native interfejsom. Medjutim, ako se uglavnom setas kroz stablo, upravo radis ono sto si rekao da ne radis, posto je uporno setanje kroz stablo u direktnoj suprotnosti sa dobro zamisljenim i optimizovanim ActionScriptom, ili je barem to moje skromno misljenje.

Setanje kroz stablo se isplati samo u dve situacije: ili ces sve da parsujes u nesto sto softver razume, ili ces sve da parsujes onako kako covek razume da bi mu to i prikazao. Nakon setanja se XML baca, nema potrebe setati se ponovo kroz njega, osim ako volis da zauzimas memoriju duplim podacima i gomilom suvisnih imena nodova koja takodje zapremaju previse.

Medjutim, ako odlucis da cuvas XML (a upravo je ovaj slucaj obradjen u primeru koji sam okacio gore), neces setati kroz njega, nego ces uzeti ono sto ti treba, kada ti treba, i bas u takvim situacijama se ForX pokazao kao savrsen alat, jer je za to i namenjen, izmedju ostalog.

Btw, sta su base-oliki XMLovi?
WhiteWeedow
Forx je stvarno jako dobra classa, na pocetku sam se predomisljao dali da radim uopste sa njim ili da odustanem. Nisam odustao i uvek cu da ga koristim u onim xml-ovima koji odgovaraju forxu i stvarno je milina raditi sa njim, zamislis ga kao bazu podataka i kazes daj mi tu informaciju pod tim id-om nista lepse.

Hteo sam jos da kazem i da pitam nesto u vezi ovoga nacina importovanja xml-a, iskreno ovde imam njamanje iskustva i najmanje znam u odnosu na druge.

Ovaj nacin nikad nisam koristio da ovako importujem xml, ali logicno je da se nece izbrisati my_xml sve dok se ponovo ta funkcia neuoptrebi.

Pa valjda je i onPress = function(){} kao i svaka druga funkcija zar ne? pa tako i onLoad znaci pozvao si je i ona ce se izvrsiti iako je lokalna jer je idalje u memomoriji samo nije dostupna s vana.

Zar nije logicno da sve variable unutar funkcije trebaju biti u memoriji sve dok se ta ista funkcija nepozove ponovo?

I posto su sve lokalne variable i dalje u memoriji iako je se funkcija zavrsila dali bi ih bilo dobro brisati na kraju funkcije?

Ja to cesto radim da ako primim neki argument na kraju funkcije ga izbrisem ili ako sam kreirao lokalnu variablu unutar funkcije i ako nosi sa sobom vise informacija nakon sto je prosledim drugoj funkciji izbrisem je iz iste? i sve lokalne koje su u toj funkciji. Ovo sam narocito cesto radio u svom zadnjem projektu sto pravim.
Running really fast smile.gif

EDIT:
Zabrovario sam da kazem da brisem da sam vrlo oprezan i precizan sta i kada i gde izbrisem.

Jer imas nekad nekoliko funkcija koje ces pozvati samo mozda 1 ili 2 puta, a kroz njih ce proci velike kolicine infomcija pupt nekih nizova ili xml i ako neizbrises te informacije na kraju funkcije zauvek ce ostati u memoriji samo nece biti dostupni. Naravno pricam samo o lokalnim variablama i argumentima koje prosledis funkciji.
MrSteel
nije dobro brisanje argumenata
brisanje promenjlivih lokalno kreiranih u funkciji je ok, mozda i preporucljivo a upravo to treba da radi GC
ne treba do ostaju promenljive funkcije u memoriji dok se ona sledeci put ne pozove 8)
njihovo postojanje treba da se zavrsi onda kada se izvrsi funkcija

to vazi samo za promenljive kreirane u funkciji
za sve parametre funkcije ili spolja vidljive promenljive zavrsetak funkcije generalno ne treba nista da menja
osim ako ti bas to nije zelja

gde su sada pointeri i alokacija memorijskog prostora biggrin.gif
WhiteWeedow
Ali i argumenat je opet postao lokalna variabla koja je unutar te funkcije i kada se zavrsi funkcija opet ce ostati unutar nje, i znaci opet filuje memoriju, ukoliko je u pitanju neki argumenat poput nekog velikog niza ili xml-a.

A zbog cega bi ga ostavio u memoriji ako ga vise nikada neces koristi. Ja isto pobrisem i globalne variable iz klasse ukoliko tu klassu necu dalje koristiti nevezano bile one private ili static.

Sve to bi trebao CG da radi sa lokalnim variablama u funkciji ali neradi nikako i to sam odavno primetio. A da radi isto nebi valjalo, tj valjalo bi ali pazi ovaj primer:

CODE
function setitems(n:Number):Void {
   x  = 10;
   for(var i:Number = 0; i < n; i++) {
      var itm:MovieClip = this.attachMovieClip("someMC", "newMC"+i, i);
      itm._x = x;
      itm.onPress = function() {
         //radi nesto
      };
   }

}

setitems(10);


Sta bi se desilo kad se sve pobrisalo unutar ove funcije? Dobro MovieClip se nece izbrisati to je jasno, a i for je funkcija u biti.

sve varible kada napises unutar funkcije kao var n:Number = 0; je nemoguce izbrisati bukvalno da je izbrises a argumenat mozes.

EDIT:
Sry nisam bio upravu za argumenat nemozes ni njega bukvalno da izbrises. recimo: delete n;
the
CITAT (syndrome @ Nov 3 2007, 12:13) *
Stvarno bih voleo da cujem sta nije u redu sa ForXom kako bih ga popravio/napravio da bude bolji.

ok setiću se pa ću ti raportirati...

CITAT (syndrome @ Nov 3 2007, 12:13) *
Nakon setanja se XML baca, nema potrebe setati se ponovo kroz njega

Ne šetam se ja po stablu već korisnik.
Kompletna struktura sajta je xml pa tako korisnik interakcijom po sajtu zapravo šeta kroz xml. njemu isto - a ja redukujem gomilu koda.
Podaci za aktuelnu stranicu ili neki njen element su uvek na aktuelnom nodu, tako da nema traženja.
Količina ovih podataka je mizerna - nisu opterećenje.

CITAT (syndrome @ Nov 3 2007, 12:13) *
Btw, sta su base-oliki XMLovi?

upravo suprotni, xml za dbase upotrebu.
syndrome
@the
Ok, skapirao sam. Stvar je u tome sto si ti tvorac XMLova koje koristis, samim tim, ForX ti apsolutno nije potreban.
Ono sto su najjaci aduti ForXa je fleksibilnost u radu, i bezbedno kreiranje i potrazivanje nodova on-the-fly. Evo sta to znaci.

Ako dobijemo sledeci XML sa servera...
CODE
<SomeXML>
  <Node1>
    <DataNode id="1" type="Yeehaa">Hello</DataNode>
    <DataNode id="2" type="empty" />
  </Node1>
</SomeXML>

...lako je napraviti rigidni parser u Flashu preko firstChild/nextSibling.
Ali kada dodje do promene, ForX je mnogo bezbedniji, jer ocekuje da pronadje DataNode, a ne DATA_NODE. Cak i ako pronadje DATANODE, imas case-insensitive opciju koja streamline-uje development.

Uostalom, mnogo je lepse gledati u
CODE
var f:Forx = new Forx(x);
var s:String = f.getPathValue("somexml.node1.datanode?id:1");
var t:String = f.getPathValue("somexml.node1.datanode?id:1@type");
nego u
CODE
var s:String = x.firstChild.firstChild.firstChild.firstChild.nodeValue;
var t:String = x.firstChild.firstChild.firstChild.attributes["type"];

Ali ovo ne bi ni radilo kako treba kada bi dosao sledeci XML (koji je semanticki identican prethodnom)...
CODE
<SomeXML>
  <Node1>
    <DataNode id="2" TYPE="empty" />
    <DataNode id="1" TYPE="Yeehaa">Hello</DataNode>
  </Node1>
</SomeXML>

...Za s bi dobio undefined umesto Hello, za t undefined umesto Yeehaa.

Pa bi morao da pises:
CODE
var s:String;
var t:String;
for(var n:XMLNode = x.firstChild.firstChild.firstChild; n != null; n = n.nextSibling) {
    if(n.attributes["id"] == "1") {
        s = n.firstChild.nodeValue;
        t = n.attributes["type"];
        if(t == undefined) t = n.attributes["TYPE"]; // ovo i dalje ne pokriva sve mogucnosti
        break;
    }
}

Ako je tebi to bolje, lakse, preglednije, i bezbednije, be my guest. Nemam nista protiv.
Ali ne mozes poreci da to nije dobra programerska praksa. Nije timski orijentisan kod, nije fleksibilan, nezgodan je za debugging i odrzavanje, i moze prouzrokovati komplikovane logicke greske negde na drugom kraju softvera. Sve ovo je u suprotnosti sa OOP doktrinom.

@ww
onPress stvarno nije bitan za taj primer gore. Mogla je da bude i neka druga sasvim legitimna metoda u pitanju. Iz nekog razloga, autor tog clanka je okacio bas takav primer, pa sam ja ponovio (jedino sam dodao my_xml.load("some.xml"); on je iz nekog razloga to preskocio).

Bas kao sto je MrSteel rekao, lokalne varijable bi trebalo da nestanu i postanu nedostupne istog trenutka kada se metoda izvrsi do kraja, bilo da izvrsenje prodje kroz sve instrukcije i dodje do dna, bilo da iskocis iz nje sa return. E sad, iako je my_xml zaista nestala i ne postoji nacin da dodjes do nje, ona je pokazivala na [XML] objekat u memoriji. Garbage collector radi tako sto gleda koliko varijabli referencira objekte. Kada taj brojac dodje do nule on unisti objekat i oslobodi memoriju. U slucaju gore, XML objekat je dosao do nule, posto je jedina varijabla koja ga je referencirala bila my_xml, a ona je nestala nakon izvrsenja metode. Ipak, posto je XML ipak dosao i onLoad callback je pozvan, zakljucujemo da XML objekat ipak nije obrisan, odnosno GC nikada nije stigao da ga ukloni, iako mu je brojac bio na nuli.

Sto se tice tvog drugog pitanja, argumenti funkcije mogu da se brisu kao i svaka druga lokalna varijabla. Argumenti funkcije se razlikuju od lokalnih varijabli samo po tome sto predstavljaju ulazni interfejs jedne metode, odnosno premoscavaju poziv funkcije i telo funkcije. Jednom kada vrednosti predju taj most (by value ili by reference, zavisno od tipa podatka; pisao sam ranije o tome), one automatski postaju lokalne varijable i prirodno nestaju nakon njenog izvrsenja. Logicno je da mozes da unistis takvu varijablu sa delete, ako to zelis, mada je to retko neophodno. Jedini slucaj koji mi pada na pamet je slucaj kada u metodu ulazi glomazna informacija by reference, recimo nekakav ogroman niz, ili citava hijerarhija objekata. Ako je cilj metode da te podatke prikaze, a zatim unisti taj blok informacija, onda delete ima savrsen smisao, posto podaci argumenata prosledjenih by reference nisu lokalni, vec pripadaju ili klasi, ili nekoj od prethodnih metoda na steku.

Anyway, kada sam hteo da ilustrujem ovo, naisao sam na jos interesantniju stvar, koja je u sustini logicna. Zbog ovoga, delete ipak ne mozes koristiti na lokalnim argumentima funkcije, osim ukoliko se radi o primitivnim podacima (koji su prosledjeni by value).

Evo za domaci, pokusaj da mi objasnis zasto ovo radi ovako kako radi:
CODE
odradiStvar();

function odradiStvar() {
    var a:Array = new Array();
    pocniNiz(a);
    zavrsiNiz(a);
    trace("ovaj niz ne bi trebalo da postoji: " + a);
}

function pocniNiz(niz:Array) {
    for(var i:Number = 0; i < 20; i++) {
        niz.push(Math.floor(Math.random() * 100));
    }
}

function zavrsiNiz(niz:Array) {
    trace("ovde kao radimo nesto, a onda unistimo niz na sve moguce nacine"); // izaberi neki od nacina: iskomentarisi ostale
    niz = [];
    niz = null;
    niz = new Array();
    delete niz;
}
WhiteWeedow
Pa ovako da krenem redom stavljat cu opise pored code-a:
CODE
odradiStvar();

function odradiStvar() {
    var a:Array= new Array();//deklarisana a NIZ
    a.push("Syndrome, mi dao domacu zadacu");//napunjena informacijom
    pocniNiz(a);//a vraibla prosledjena funkciji pocni niz kao referenca.. gledaj pocniNiz(); funciju
    zavrsiNiz(a);//zavrsimo niz tacnije ispraznimo variablu a koja je
    //prosledjena kao referenca.. gledaj funkciju zavrsiNiz();
    trace("ovaj niz ne bi trebalo da postoji: " + a + "  niz postoji ali je prazan trenutno, jer smo ga dole ispraznili");
    //izbrisi a totalno
    delete a;
    trace("a variabla je izbrisana iz memorije u potpunosti " + a + " niz nepostoji nikako");
    
}

function pocniNiz(niz:Array) {
    //funkcija prima referencu
    //niz punimo kroz for pelju
    for(var i:Number = 0; i < 20; i++) {
        niz.push(Math.floor(Math.random() * 100));
    }
    //brisi niz lokalnu varibalu iz scopa ove funkcije pocniNiz();
    niz = null;
    //pocniNiz(); je ociscena funkcija kojatrenutno nema nikakvih informacija
    //koje bi mogle da pune memoriju playera
}

function zavrsiNiz(niz:Array) {
    trace("ovde kao radimo nesto, a onda unistimo niz na sve moguce nacine"); // izaberi neki od nacina: iskomentarisi ostale
    niz.splice(0, niz.length);// ispraznimo referencu totalno, tacnije varibalu a koja je deklarisana
    //u funkciji odradiStvar();,
    
    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
    //ukoliko zelimo da izbrisemo referencu tj lokalnu variablu niz iz scopa ove funkcije to cemo
    //uraditi opet na sledeci nacin
    niz = undefined;
    
    //referencu nemozemo da izbrisimo ni na jedan nacin jer je deklarisana kao lokalna... pogledaj jos
    //funkciju odradiStvar();
}


Mada za null nisam siguran u funkciji pocniNiz();, mozda je bolje bilo da sma i gore stavio undefined?

EDIT:

Zaboravio sam da iskomentarisem sledece:
niz = [];
niz = new Array();

Znaci sa ovim necemo da menjamo izvorno stanje reference tacnije variable 'a' koja je deklarisana u funkciji odradiStvar();.

Ukoliko stavimo niz = new Array(); ovim smo samo kreirali novi niz unutar funkcije zavrsiNiz() i prekinuli tako reci konekciju sa referencom jer je referenca postala novi niz unutar iste funkcije i nenosi inframcije varibale 'a', a nismo nista promenili u variabli 'a'.

Tako bi to objasnio syndrome ce to sigurno lepse objasniti, al uglavnom se vidi o cemu pricam.
Syndrome koliko sam shvatio? oceni domacu smile.gif
the
ne vidim kako je opisati neku konkretnu strukturu - loša programerska praksa...
a da li to radim ja ili to radi cms - krajnje je nebitno.

ti i dalje pričaš o forx-u... otkuda on uopšte kao tema sad?
syndrome
@the
Ne znam, pricali smo o XMLu, ForX je dosao sam po sebi.

Tj. napravio si cudnu podelu na "nas nacin" i "tvoj nacin" i odjednom BAM -- postoje razni nacini u hendlovanju XMLa i programeri se dele na "nas" i "vas" kada je XML u pitanju.

Logicno je da sam pretpostavio kako je ForX verovatno manifest mog, odnosno "naseg nacina" i sad sam radoznao zasto je to tako, odnosno po cemu se tvoj nacin razlikuje od ForXovog nacina, i zasto je taj nacin los.

Jer da nije los, valjda bi ga koristio?

Ne znam za tvoje nacine u sustini, i zato sam valjda i radoznao, ali moji nacini su se do sada pokazali kao kvalitetni u okruzenjima koja se konstantno menjaju, kao sto tokom multitier developmenta obicno biva.

Ja koristim XML za komunikaciju pre nego za feed podataka, otud i moja zelja da napravim dinamicki failsafe sistem za parsing XMLa. Data feed nikad nije bio previse zahtevan, zato sto ga projektujem sam i krojim prema meri. Nikada ne bih ni napravio ForX da se na tome zavrsilo.

Anyway, u medjuvremenu je nastao AmpleKit, i kada je stvar narasla, pretvorila se u neku vrstu CMSa. Gvozden je radio u AmpleKitu i mogao je da vidi kako je ForX embedovan u citavu stvar. WhiteWeedow je takodje video taj bitan deo, koji vozi citavu stvar. Neko bi rekao da je to parser, a meni sve vise lici na engine, jer je prosiriv i sofisticiran u nacinu na koji radi.

Ako ForX ne valja, onda citav jedan AmpleKit engine ne valja. Prirodno je da bih voleo da znam kako i zasto. Zato smo otisli u pravcu ForXa.

Uostalom, ovo je moja tema, mogu valjda da odem u offtopic? smile.gif

@ww
Uh, al' si se raspisao smile.gif
Nisam mislio da menjas kod, samo da izaberes neki od nacina na koji ces unistiti niz u funkciji zavrsiNiz.

Poenta je u tome da mi objasnis kako radi taj kod koji sam stavio, i da mi objasnis zasto se niz ipak ne obrise, iako mu je eksplicitno stavljen, recimo delete niz na kraju funkcije.

Izvrsi recimo ovaj kod:
CODE
odradiStvar();

function odradiStvar() {
var a:Array = new Array();
pocniNiz(a);
zavrsiNiz(a);
trace("ovaj niz ne bi trebalo da postoji: " + a);
}

function pocniNiz(niz:Array) {
for(var i:Number = 0; i < 20; i++) {
niz.push(Math.floor(Math.random() * 100));
}
}

function zavrsiNiz(niz:Array) {
trace("ovde kao radimo nesto, a onda unistimo niz na sve moguce nacine");
delete niz;
}

Rezultat trejsa ce biti:
CITAT
ovde kao radimo nesto, a onda unistimo niz na sve moguce nacine
ovaj niz ne bi trebalo da postoji: 16,3,39,38,42,17,34,13,64,2,79,87,27,42,8,95,56,60,98,89

Mislio sam da mi objasnis zasto je to tako. Zasto je napisao ovaj niz ne bi trebalo da postoji: 16,3,39,38,42,17,34,13,64,2,79,87,27,42,8,95,56,60,98,89?

Interesantno je, i zahteva razumevanje ActionScripta izvan onoga sto je ponudjeno i bilo kojoj knjizi.

Evo objasnicu, da ne gubimo vreme.

U odradiStvar metodi, kreiramo objekat Array i definisemo lokalnu promenljivu tako da pokazuje na taj objekat. U toj istoj metodi se pozivaju pocniNiz i zavrsiNiz.

Ka obe metode se prosledjuje ta lokalna varijabla koja pokazuje na niz, i posto je niz kompleksan tip, nece se proslediti po vrednosti, nego po referenci. To znaci da ce, kada pozovemo pocniNiz, ova metoda raditi nad nizom koji pokazuje ova varijabla. Konkretno, napunice ga nekakvim brojevima.
Kada se pozove zavrsiNiz, ovde bi trebalo da se taj niz unisti.

Medjutim, a to je ono sto sam hteo da pokazem, taj niz ne mozes nikako da unistis preko argumenta (osim ako koristis interfejs samog niza). Varijabla niz koja se definise onog trenutka kada pocne da se izvrsava zavrsiNiz, ne moze nikako da utice na objekat u memoriji.
  • Ako stavis niz = []; ili niz = new Array(); otvorice se novi objekat Array tipa u memoriji. To nece ugroziti originalni niz, vec ce varijabla samo prestati da pokazuje na njega.
  • Ako stavis niz = null;, varijabla ce biti dereferencirana, ali ni to nece ugroziti originalni niz.
  • Ako stavis delete niz;, obrisace se lokalna varijabla niz, ali ni to nece ugroziti originalni niz, jer na njega vec pokazuje varijabla iz odradiStvar.

Drugim recima, ne mozes nikako (preko argumenta) da ubijes objekat koji je prosledjen by reference. Dokle god ona varijabla a pokazuje na taj objekat, GC nece doci da ga ubije i moci ces da mu pridjes iz scope-a funkcije u kojoj je definisan, sve dok se ta funkcija ne izvrsi.

Zbog toga, sta god da izaberes od ovoga, u odradiStvar ce se preko varijable a opet trejsovati onaj isti niz koji je napunjen u pocniNiz.
WhiteWeedow
Oki uglavnom sam dobro razumeo kako sve ide.

Sto se tice ovog code-a:
CODE
odradiStvar();

function odradiStvar() {
    var a:Array = new Array();
    pocniNiz(a);
   zavrsiNiz(a);
   trace("ovaj niz ne bi trebalo da postoji: " + a);
}

function pocniNiz(niz:Array) {
   for(var i:Number = 0; i < 20; i++) {
      niz.push(Math.floor(Math.random() * 100));
   }
}

function zavrsiNiz(niz:Array) {
    trace("ovde kao radimo nesto, a onda unistimo niz na sve moguce nacine");
    delete niz;
}


Logicno da delete ovde nece odraditi posao i nece izbrisati 'niz' iz scopa ove funkcije, jer je orginalna variabla 'a' na koju pokazuje 'niz' lokalna variabla, vec unapred definisana u funkciji odradiStvar(), tako da nemamo uopste pristup variabli 'a'.
U ovom slucaju mozemo da uradimo niz = undefined; da bi izbrisali lokalnu varibalu koja se nalazi u funkciji zavrsiNiz();

Jer delete u biti brise globalne variable i lokalne, ali samo one lokalne koje su definisane u istoj funkciji gde se nalazi i sam delete operator.
syndrome
^ nije bas tako.

Evo ilustrovao sam celu stvar, valjda ce to pomoci:


  • odradiStvar(); - Unutar ove funkcije, kreira se objekat tipa Array (new Array()) na koji pokazuje upravo napravljena lokalna varijabla a (var a:Array).
  • pocniNiz(a); - Ovim se prosledjuje referenca koju ima varijabla a, metodi pocniNiz. Ta funkcija kreira novu lokalnu varijablu niz kojoj se prosledjuje referenca na onaj isti Array objekat (niz se samim tim moze nazvati argumentom funkcije, iako se tehnicki ni po cemu ne razlikuje od varijable). pocniNiz menja podatke Array objekta tako sto pristupa njegovom interfejsu (metoda push). Zbog toga su promene permanentne, jer je u pitanju jedan jedini Array objekat.
  • zavrsiNiz(a); - Ovo je stanje kada se pozove funkcija zavrsiNiz. Vazi sve sto je receno gore.
  • delete niz; - Ako pokusamo unutar funkcije zavrsiNiz da obrisemo varijablu niz, dobicemo ovo. Unistava se entry ove varijable (odnosno, postaje nedostupna), a zajedno sa njom nestaje i referenca na Array objekat. Medjutim, Array objekat nece biti unisten, zato sto varijabla a iz funkcije odradiStvar i dalje pokazuje na njega.
  • niz = null; ili niz = undefined; - Ako pokusamo unutar funkcije zavrsiNiz da ponistimo referencu varijable niz na Array objekat, to ce se i desiti. Referenca ce biti ponistena, ali i dalje Array objekat nece biti unisten, zato sto varijabla a pokazuje na njega.
  • delete a; - Konacno, ako pokusamo u funkciji odradiStvar da obrisemo varijablu a sa njom ce nestati i referenca na Array objekat. Nakon toga, Array objekat ostaje bez referenci i garbage collector ce ga obrisati posle nekog vremena iz memorije.

Eto, nadam se da je sad jasno.
the
nema "mog" i "tvog/vašeg" načina... mislio sam na konkretan primer u kome xml deklarišeš u anonimnoj funkciji kratkog veka, pa to uporedio sa mojom navikom da xml čuvam kao "oko u glavi".
pri tome ne umanjujem vrednost forx-a već mu u konkretnoj situaciji ne nalazim primenu, jer mi i treba predvidljivo konstantna šetnja od roditelja ka detetu i nazad.

što se pokušaja upotrebe forx-a tiče, problem je pravila getMultiNodes metoda. nema šanse da se setim konkretne situacije ali nisam dobijao planirani rezultat. na kraju je bilo jednostavnije napisati dve linije "izokola" koda nego vijati modus koji šljaka.

usput, za konkretan primer mi je trebao "xml operativni" podskup nodova istog roditelja, a niz takvih nodova koje bih dobio sa getMultiNodes bih morao ponovo da konvertujem u xml.
konkretno sam na to mislio kada sam spomenuo moj/tvoj način... ja bih, operišući već sa xml-om, očekivao da mi funkcija vrati xml a ne array.

anyway, forx je odličan za komunikaciju, ali ja xml uglavnom koristim za definiciju linijskog kretanja po strukturi...
syndrome
^ Ok, jasno, nisi to lepo formulisao u startu.

U pravu si sto se tice getMultiNodes. Ta metoda ne radi ni upola onoga sto bih ja zeleo da radi. Howeva, getMultiNodes je ubacen tek u poslednjoj minor verziji 0.7 i ubacio sam je bukvalno kao extended varijantu getPathNode-a. Ima jos puno da se radi na tome. Zato mi je i potreban feedback, upravo od ljudi kao sto ste ti i MrSteel, zato sto radite sa XMLom onako kako sam zamislio sopstvenu ciljnu grupu.

Ideja je da stvorim alat koji ne radi na moj nacin, nego je univerzalan i dovoljno dobar i za moju, i tvoju i MrSteelovu implementaciju. Tek tada cu biti zadovoljan.

U sustini, kako sada stvari stoje, ForX je 60-70% potrazivanje, 30-40% kreiranje i manipulacija XMLom.

Postoji nacin da se jednostavno izvede to sto ti je trebalo, ali je kroz workaround.

getMultiNodes radi identicno getPathNode-u. Jedina razlika izmedju ova dva je u tome sto getPathNode vraca samo onaj nod koji se uklapa u query, a getMultiNodes vraca niz svih nodova koji se uklapaju u query. Prednost vracanja niza je u tome sto metoda nije destruktivna, vec ti daje reference na nodove, cime ti je i dalje dostupna originalna struktura XMLa kroz sam rezultat.

Evo jedne interesantne primene getMultiNodes:
CODE
<ImageFolder>
<Image id="4" type="public" thumb="thumbs/campus_winter_nature.jpg">Winter Campus</Image>
<Image id="11" type="public" thumb="thumbs/scenic_winter4.jpg">Scenic Winter</Image>
<Image id="15" type="hidden" thumb="thumbs/Winter_in_raleigh_smaller.jpg">Winter In Raleigh</Image>
<Image id="5" type="public" thumb="thumbs/maine-pine-haven-winter-par.jpg">Pine Haven</Image>
<Image id="20" type="public" thumb="thumbs/winter-view-photo.jpg">Winter Cottage</Image>
<Image id="0" type="hidden" thumb="thumbs/AB5515~Winter-Awakening-Pos.jpg">Winter Awakening</Image>
<Image id="3" type="public" thumb="thumbs/branch-snow_winter.jpg">Branch</Image>
<Image id="18" type="public" thumb="thumbs/winter-3d-screensaver_1.jpg">Snowy Plains</Image>
<Image id="7" type="public" thumb="thumbs/peak_district_winter_avidim.jpg">Peak District</Image>
<Image id="8" type="public" thumb="thumbs/rememberwinter1280x1024ls.jpg">Remember Winter</Image>
<Description>Winter photos</Description>
<Copyright year="2007">Various Artists</Copyright>
<Image id="9" type="public" thumb="thumbs/rus-winter.jpg">Russian Winter</Image>
<Image id="14" type="hidden" thumb="thumbs/winter_foto_pixelquelleWann.jpg">Winter Beach</Image>
<Image id="19" type="hidden" thumb="thumbs/winter-scenes_340.jpg">Arctic Landscape</Image>
<Image id="10" type="public" thumb="thumbs/sapporo-winter-3.jpg">Sapporo Winter</Image>
<Image id="1" type="public" thumb="thumbs/Batsto_Horse_Barn_Winter_.jpg">Horse Barn</Image>
<Image id="2" type="public" thumb="thumbs/black_fruit_in_the_snow.jpg">Black Fruit In The Snow</Image>
<Image id="13" type="public" thumb="thumbs/winter.jpg">Winter Night</Image>
<Image id="6" type="public" thumb="thumbs/mild-winter-3d-screensaver.jpg">Mild Winter</Image>
<Image id="17" type="hidden" thumb="thumbs/winter2_03.jpg">Urban Chill</Image>
<Image id="12" type="hidden" thumb="thumbs/winter(2).jpg">White Trees</Image>
<Image id="16" type="public" thumb="thumbs/winter2.jpg">Mountain Road</Image>
</ImageFolder>


CODE
import com.orionSyndrome.xml.Forx;

class com.orionSyndrome.Stuff {

  private var __copyright:Object;
  private var __sDescription:String;
  private var __xmlImages:XML;
  private var __images:Array;

  public function Stuff(sUrl:String) {
    __loadData(sUrl);
  }

  private function __loadData(sUrl:String):Void {
    var $class = this;

    __xmlImages = new XML();
    __xmlImages.ignoreWhite = true;

    __xmlImages.onLoad = function(fSuccess:Boolean) {
      if(fSuccess) {

        with($class) {
          
          var t:Number = getTimer();
          
          __parseCommonInfo();
          __parseImages();
          
          trace("Parsing time: " + (getTimer() - t) + " milliseconds");
          trace("--");
          
          __dumpStuff();
        }

        delete this;
      }
    }

    __xmlImages.load(sUrl);
  }

  private function __parseCommonInfo(Void):Void {
    var f:Forx = new Forx(__xmlImages);
    
    var xnCopy:XMLNode = f.getPathNode("imagefolder.copyright");
    
    __copyright = {
      year: f.getPathValue("@year", xnCopy),
      owner: f.getPathValue(null, xnCopy)
    }
    
    __sDescription = f.getPathValue("imagefolder.description");
    
  }

  private function __parseImages(Void):Void {
    __images = new Array();

    var f:Forx = new Forx(__xmlImages);
    var nodes:Array = f.getMultiNodes("imagefolder.image?type:public");

    var image:Object;

    for(var iNode:Number = 0; iNode < nodes.length; iNode++) {
      image = {
        thumb: f.getPathValue("@thumb", nodes[iNode]),
        caption: f.getPathValue(null, nodes[iNode])
      }

      __images[Number(f.getPathValue("@id", nodes[iNode]))] = image;
    }
    
  }
  
  private function __dumpStuff(Void):Void {
    trace("Description: '" + __sDescription + "'");
    trace("Copyright (c) " + __copyright.year + " by " + __copyright.owner);
    
    for(var i:Number = 0; i < __images.length; i++) {
      trace("Image " + i + ":");
      
      if(__images[i] != undefined) {
        trace("  caption: '" + __images[i].caption + "'");
        trace("  thumb: '" + __images[i].thumb + "'");
        
      } else {
        trace("  (empty slot)");
        
      }
    }
  }
  
}


Da, bacio sam XML koji sam ucitao.
Medjutim, taj XML je mogao lako biti deo neke vece strukture i mogao je biti samo prosledjen ovoj klasi, bez unistavanja.

Primer je mozda malo cudan, ali ne znaci da takav slucaj ne mora da postoji. Stavise, bas sam danas pravio nesto slicno.

Namerno sam podelio slike na dva tipa: public i hidden, bez nekog posebnog razloga.
Klasa smesta slike u odgovarajuce slotove (prema id-u noda) koji su sortirani na kraju, i usput izbegava hidden slike. Drugim recima, rezultat ima nekolicinu praznih slotova koji su ili definisani prazni (tj. nisu popunjeni u XMLu), ili su sadrzali hidden sliku.

Evo kako izgleda rezultat:
CODE
Parsing time: 7 milliseconds
--
Description: 'Winter photos'
Copyright © 2007 by Various Artists
Image 0:
(empty slot)
Image 1:
caption: 'Horse Barn'
thumb: 'thumbs/Batsto_Horse_Barn_Winter_.jpg'
Image 2:
caption: 'Black Fruit In The Snow'
thumb: 'thumbs/black_fruit_in_the_snow.jpg'
Image 3:
caption: 'Branch'
thumb: 'thumbs/branch-snow_winter.jpg'
Image 4:
caption: 'Winter Campus'
thumb: 'thumbs/campus_winter_nature.jpg'
Image 5:
caption: 'Pine Haven'
thumb: 'thumbs/maine-pine-haven-winter-par.jpg'
Image 6:
caption: 'Mild Winter'
thumb: 'thumbs/mild-winter-3d-screensaver.jpg'
Image 7:
caption: 'Peak District'
thumb: 'thumbs/peak_district_winter_avidim.jpg'
Image 8:
caption: 'Remember Winter'
thumb: 'thumbs/rememberwinter1280x1024ls.jpg'
Image 9:
caption: 'Russian Winter'
thumb: 'thumbs/rus-winter.jpg'
Image 10:
caption: 'Sapporo Winter'
thumb: 'thumbs/sapporo-winter-3.jpg'
Image 11:
caption: 'Scenic Winter'
thumb: 'thumbs/scenic_winter4.jpg'
Image 12:
(empty slot)
Image 13:
caption: 'Winter Night'
thumb: 'thumbs/winter.jpg'
Image 14:
(empty slot)
Image 15:
(empty slot)
Image 16:
caption: 'Mountain Road'
thumb: 'thumbs/winter2.jpg'
Image 17:
(empty slot)
Image 18:
caption: 'Snowy Plains'
thumb: 'thumbs/winter-3d-screensaver_1.jpg'
Image 19:
(empty slot)
Image 20:
caption: 'Winter Cottage'
thumb: 'thumbs/winter-view-photo.jpg'


Kod se moze skinuti ovde (Flash 8).

Planiram da napravim getMultiNodes jos kompleksnijim i mocnijim u buducnosti, ali mi je potreban feedback da bih uspeo u tome.
WhiteWeedow
Hvala puno Syndrome i sve sam razumeo ali delete nisam nikako buni me nesto:

CITAT
delete niz; - Ako pokusamo unutar funkcije zavrsiNiz da obrisemo varijablu niz, dobicemo ovo. Unistava se entry ove varijable (odnosno, postaje nedostupna), a zajedno sa njom nestaje i referenca na Array objekat. Medjutim, Array objekat nece biti unisten, zato sto varijabla a iz funkcije odradiStvar i dalje pokazuje na njega.


Hoces reci da ako uradis delete niz; unutar funkcije zavrsiNiz(); da tada vise neces moci pristupati referenci variable 'a' (tj objektu Array na kojeg variabla 'a' pokaziva), preko lokalne variable niz , jer lokalna variabla niz vise nece imati referencu na taj isti Array objekat?

EDIT:

Ovako si mislio:

CODE
function zavrsiNiz(niz:Array) {
    delete niz; //variabla a se nece izbrisati tj objekat Array na kojeg var a pokaziva.
    niz.push("after delete"); //posle delete niz; ovo vise nece menjati Array objekat na kojeg pokaziva "a" variabla
}
the
vi'š ti to... uhvatim se za forx i o'ma za ono što ne radi wink.gif

nije frka za forx, biće primene... već sam negde napisao da je dušu dao za integraciju sa swfAddress. samo da se raščisti situacija oko toga šljaka li ovaj u ...king adobe playeru.
syndrome
CITAT (WhiteWeedow @ Nov 5 2007, 20:22) *
Ovako si mislio:
Bas tako. Ako niz ne vidi vise Array objekat, ne moze ni da pridje njegovom interfejsu, a push metoda je deo tog interfejsa.
Prakticno, sa delete obrises niz, ali ne obrises ono na sta niz pokazuje.

U generalnom slucaju, kada uradis
CODE
var obj:Object = new Object();
delete obj;

...ne brises objekat, nego varijablu obj.
GC brise objekat kada shvati da niko vise ne pokazuje na njega.

Isto tako, mozes (i trebalo bi) da shvatis new kao operator koji kreira anonimni objekat i vraca referencu na njega.
A posto smo napisali obj = new Object();, ta referenca se dodeljuje varijabli obj.

U sustini, to je osnova objektnog programiranja, koju uvek nekako preskocim da kazem kada pricam o tome.
Uvek sam mislio da je to previse skolski i dosadno, ali vazno je reci pre ili kasnije da varijabla i objekat nikad ne zavise jedno od drugog.
Varijabla je kao prozor, pa cak i kad pokazuje na primitivan podatak (broj, tekst, true/false...), ili nikakav podatak (undefined), ili specijalan podatak (null). Pravi podatak je negde drugde, a sa objektima to samo postaje malo ociglednije. Sreca pa ActionScript nema pointere smile.gif To bi bilo ludo objasniti biggrin.gif

Sad sa tim saznanjem pokusaj da shvatis sta se desava sa onim primerom u postu #1

@the
Pa nije bas da ne radi. Pre bih rekao da si ocekivao nesto drugo... Verovatno.
U svakom slucaju bih voleo da znam: ako ne radi, sta ne radi, ako je trebalo da radi nesto drugo, sta je to... I tako to.
WhiteWeedow
CITAT (syndrome @ Nov 5 2007, 21:43) *
Bas tako. Ako niz ne vidi vise Array objekat, ne moze ni da pridje njegovom interfejsu, a push metoda je deo tog interfejsa.
Prakticno, sa delete obrises niz, ali ne obrises ono na sta niz pokazuje.


Al nebi se slozio u ovom slucaju da delete brise lokalnu variablu niz.
Jer delete ce obrisati lokalnu variablu samo ako je lokalna var dostupna u ovom slucaju nije dostupna, jer niz variabla nije nigde deklarisana u funkciji zavrsiNiz(); jer ona je samo argument u ovom slucaju, argumente nemozemo da brisemo sa delete niti bilo sta da menjamo pomocu operatora delete kad je upitanju argument.


Ajmo testirati:

CODE
odradiStvar();

function odradiStvar() {
    var a:Array = new Array();
    pocniNiz(a);
    zavrsiNiz(a);
    trace("prikazi niz i njegove promene: " + a);
}

function pocniNiz(niz:Array) {
    for(var i:Number = 0; i < 10; i++) {
        niz.push(Math.floor(Math.random() * 100));
    }
}

function zavrsiNiz(niz:Array) {
    delete niz; //pokusaj brisanja lokalne var niz iz scopa ove funkcije
    niz.push("after delete");//ovo nebi trebalo nakon delete operatora da nemenja referencu variable 'a' tj objekat Array na kojeg ona pokaziva.
    //znaci nemozemo argumente da brisemo sa delete ili da bilo sta drugo da uradimo sa delete argumentu 'niz'
       trace(niz);
}
syndrome
^ Da, ali samo zato sto je zakljucana, a ne zato sto je po bilo cemu specijalna.

Mozda da probas ovako, da vidimo dal' ne moze da se obrise wink.gif

CODE
odradiStvar();

function odradiStvar() {
    var a:Array = new Array();
    pocniNiz(a);
    zavrsiNiz(a);
}

function pocniNiz(niz:Array) {
    for(var i:Number = 0; i < 20; i++) {
        niz.push(Math.floor(Math.random() * 100));
    }
}

function zavrsiNiz(niz:Array) {
    trace("PRE: " + niz);
    _global.ASSetPropFlags(niz, null, 0, 0);
    delete niz;
    trace("POSLE: " + niz);
}


Argument je ... (edit: rasplinuo sam se ovde, pa sam obrisao.. mogu pisati o tome drugi put)

Po meni je pogresno sto su argumenti zakljucani (zato sto to daje argumentima tretman koji ne zasluzuju), ali moguce je da postoje neke implikacije koje meni nisu pale na pamet, a Macromediji jesu.

U svakom slucaju, gore sam vec pokazao da nema mnogo koristi od brisanja argumenata. Moguce je da su i oni zakljucili isto to, i da su zakljucali argumente upravo zbog toga sto ni sami nisu sigurni da li to moze dovesti do nezeljenih rezultata u nekim situacijama.

Status kvo.
MrSteel
posledica koncepcije,
arguments je tipa Object,
syndrome
Ne verujem da to ima veze sa ovim. Taj arguments objekat pripada generickom prototipu same funkcije. Najobicniji niz koja se kreira po izvrsavanju funkcije, na osnovu onih parametara koji su prosledjeni.

U stvari, uvek sam se pitao, zasto ECMAScript ne podrzava named arguments sintaksu, kada ima sve sastojke za to. Pretpostavljam da je zbog toga sto ni kompajler ni interpreter nisu striktni u tipiziranju. Zbog loose tipizacije su i presli na AS3, jer je postalo pretesko peglati nesto sto nije zamisljeno rigidno, sa sve predefinisanim imenima parametara i jasnim i preciznim deklaracijama.

Jer kao sto svi znamo, mozes pozvati funkciju na potpuno deseti nacin od onoga sto je definisano deklaracijom (za razliku od Jave, AS je kao sundjer; mada nikad nisam voleo onaj djavo 'polimorfizam' u Javi -- jedina stvar gora od toga su pointeri u C-u).

CITAT (arguments)
Note that there may be a different number of arguments passed in than the function declares.

Kako god IMHO, nema logike zabraniti izbacivanje objekta iz niza u ovom slucaju koji je pokazao ww.

arguments je zamisljen kao user-convenience (da bi mogao da iteriras kroz argumente), i verovatno je usvojen iz Jave koja je pokusala da objektom zameni argc i argv u C-u. To je posledica, pre nego uzrok.

Cudna i zanimljiva stvar, u svakom slucaju.
MrSteel
mislio sam samo na pricu o brisanju argumenata, sasvim je jasno zasto ne mozes obrisati originalnu promenljivu
da baratamo sa pointerima onda bi moglo sve
pointer - pokazivac na memorijsko mesto,
evo najavili su da ce array biti tipiziran, ECMA4
http://aralbalkan.com/1072
syndrome
Ima fora kako moze da se extenduje Array u ASu2 (moses je to uradio u Fuse-u; zezao sam se tim da vidim kako radi, ispostavilo se da je tezak workaround, ali stabilan).

Ako te to interesuje, mozemo da se zezamo da probamo da napravimo TypedArray klasu za AS2. Ne bi trebalo da bude toliko tesko. Malo egzibicija nije na odmet smile.gif
WhiteWeedow
Da radi radi smile.gif brise niz ako udaris ASSetPropFlags.

Ali ASSetPropFlags mi je poznato tj naisao sam negde na ovo ali u helpu nisam sigurno, ovo je neki hack?

Posto vidim da je brisanje argumenata jako skakljivo i po defaultu je zakljucano tako reci, sta onda kazete na undefined, tj u ovom slucaju niz = undefined;?

Naravno da necemo lokalnu var niz izbrisati u podpunosti ali cemo ukloniti vrednost koju ona nosi po meni je to onako ok da se nekad uradi ukoliko je upitanju neka lokalna neki argument koji nosi vecu kolicinu informacija?
MrSteel
bilo bi super imati primer kada je dobro unistavati argumente
ja ne mogu da osetim potrebu za tim, klasa ima svoje promenljive
klasa sama unistava svoje promenljive

mene cela ova prica nesto posebno ne interesuje zaista biggrin.gif
interesantniji su mi papervision, koncepti organizacije as projekata i sl.
argumenti ne mogu da se obrisu ili bilo sta sa njima posto je argument objekat, koji sadrzi prekopirane argumente u taj arguments objekat
koncepcija je takva i stoga sa originalnom promenljivom funkcija nema dodirnih tacaka osim sto je dobila vrednost
WhiteWeedow
Da classa ce da unisti svoje promenljive ali tek kada je upotrebis ponovo.
U biti volio bih uvek da pobrisem sve lokalne i globalne(sa globalnim ima resenje) promenljive u svim onim funkcijama koje se upotrebljavaju retko u nekoj aplikaciji, a nose veliku kolicinu informacija, znaci neke funkcije koje barataju sa nizovima ili mozda xml-om itd...

Mislim da ima neko elegantno resenje za ovo i mislim da bi bilo od koristi. Mozda syndrome nesto provali smile.gif.
A mozda je i undefined jedno od resenja?
MrSteel
jedno je brisanje lokalnih promenljivih a drugo brisanje parametara funkcije
ja bi to nazvao nekorektnim programiranjem
niko ne ocekuje takvo ponasanje od stvari koje bi koristio u radu
al ok, budzi sto da ne
syndrome
CITAT (MrSteel @ Nov 6 2007, 13:09) *
bilo bi super imati primer kada je dobro unistavati argumente
ja ne mogu da osetim potrebu za tim, klasa ima svoje promenljive
klasa sama unistava svoje promenljive

Potpuno tacno. Kao sto sam vec (tri puta) rekao, ne vidim nikakvu primenu u brisanju argumenata, uglavnom zato sto su kratkog veka i zato sto se podrazumeva da postoji nekakva arhitektura koda kojom se to moze izbeci i pre nego sto dodje do potrebe za tim.

@MrSteel
Nisi mi odgovorio za TypedArray? Ili jesi?
MrSteel
jesam, meni ne treba jer je inace AS2 opusteno programiranje tako da jedna stvar koja bi smanjivala mogucnosti za gresku ne bi puno znacila, generalno mi ne treba ali moze da se uradi nije frka biggrin.gif
fifson
odkako ste poceli pricati o ovome svi su zanijemili,ja ovo nista nemrem skontat al opet zanimljivo vidjet kako se shutate sa tim nizovima,argumentima funkcijama... samo dokle ovako pocinjete da ubijate u ljudima i ono malo samopuzdanja glede znanja o flashu biggrin.gif
syndrome
Znam kako vam je.. Tako se ja osecam svaki dan kad pricamo o preloaderima i smanjivanju zvuka, samo obrnuto.

Tesko je naci modus na ovom forumu. Ponekad se zapitam kako imam strpljenja uopste, pogotovo kada neko krene da proziva i da pravi budale od nas, umesto da nauci nesto.

Steta je, posle cete svi vi koji slusate morati da lovite hintove po guglu, umesto da ovakvih tema bude vise pa da svi napredujemo.
WhiteWeedow
Znam postajem vec extra dosadan al opet mi nije jasno zasto bi drzali duple informacije u memoriji.
Nemoj te se sad ljutiti Syndrome i Steel smile.gif.

Pazi ovaj primer, ali ovo vazi samo kod funkcija kod kojih smo unapred deklarisali neku var koja ceka da primi argument.

CODE
odradiStvar();

function odradiStvar() {
    var a:Array = new Array("before pocniNIz()");
    pocniNiz(a);
    zavrsiNiz(a);
    trace("prikazi niz " + a);
}

function pocniNiz(niz:Array) {
    trace("ARGUMENTS " + arguments[0]);
    trace("LOAKL NIZ " + niz);
    delete arguments[0];
    for(var i:Number = 0; i < 10; i++){
        niz.push(Math.round(Math.random()*100));
    }
    
    trace("ARGUMENTS " + arguments[0]);
    trace("LOAKL NIZ " + niz);
}

function zavrsiNiz(niz:Array) {
    trace("ARGUMENTS " + arguments[0]);
    delete arguments[0];
    niz.push("finished");
}


Komentarisat cu funkciju zavrsiNiz();
Znaci u funkciji odradiStvar() deklarisali smo varablu 'a' koja pokaziva na objekat Array, prosledili smo je funkciji zavrsiNiz(), u funkciji zavrsiNiz() kako ga ja nazivam u polju za pass parameters smo kreirali lokalnu var 'niz' koja prima referencu variable 'a' tacnije objekat Array na kojeg ona pokazuje, objekat Array je postao argument kojeg je primila variabla 'niz' i od toga trenutka kada je var 'niz' primila argument imamo tako reci dvije stvari koje pune memoriju i u isto vreme pokazuju na isti objekat Array i sa obe stvari mozemo da manipulisemo objekat Array, stim sto su one povezane unutar funkcije zavrsiNiz() tacnije receno kad objekat Array punimo pomocu var niz puni se i arguments[0] jer je niz primila arguments[0] i pokaziva na njega i postala je argument.

Znaci od sada imamo var niz koja puni memoriju jer je preuzela ulogu argumenta i plus sam arguments[0] koji takodje puni memoriju, sto znaci da arguments[0] mozemo komotno da izbrisemo iz memorije jer tu ulogu argumenta[0] je preuzela var niz koju smo unapred deklarisali u delu funkcije koju ja zovem area for pass parameters.

Ukoliko arguments[0] neobrisemo a nastavimo da manipulisemo var niz recimo sa metodom push() u isto vreme ce se puniti i arguments[0] sto nam je totalno nepotrebno zar ne? Pa zato i jesmo deklarisali var niz koja preuzela ulogu argumenta i koja nam je bitna da znamo sta smo primili i koju vrstu podataka i onda arguments[0] brisemo.

Ukoliko nam nije vazno sta primamo koju vrstu podataka, tj ukoliko unapred znamo da ce ta funkcija 100% reicmo primiti array netrebamo ni deklarisati var toga tipa unutar area for pass parameters nego mozemo direktno da radimo sa arguments[0], ili cak jos bolje cim udje u funkciju proveriti ga i posle na kraju kada se sve zavrsi lepo ga obrisati sa delete argumnts[0].

Malo sam spetljano objasnio al verujem da kroz primer znate sta mislis. smile.gif

EDIT:

primer da razjasnim:
CODE
function pocniNiz(niz:Array) {
       niz = undefined;
    for(var i:Number = 0; i < 10; i++){
        arguments[0].push(Math.round(Math.random()*100));
    }
    delete arguments[0];
    trace("LOAKL NIZ " + niz);
    trace("ARGUMENTS " + arguments[0]);
    
}
syndrome
CITAT (WhiteWeedow @ Nov 8 2007, 10:45) *
Znam postajem vec extra dosadan al opet mi nije jasno zasto bi drzali duple informacije u memoriji.
Prvo mi objasni ovo. Koje duple informacije?
WhiteWeedow
Pa lepo primili smo arguments[0] to je Array objekat ali ulogu argumenta je preuzela lokalna var niz, ali arguments[0] jos uvek postoji pored nje, a zasto bi postojao? Jer u isto vreme radimo i sa vriablom niz koja je preuzela ulogu argumenta[0] i pokaziva na objekat Array i sam arguments[0] koji takodje pokaziva na objekat Array. Malo tekos objasniti.

Ali arguments[0] mozes da pobrises netrebati vise jer jer var niz preuzela tu ulogu?
MrSteel
super je sto se cimas WW ali Flash nije open source
dakle tako je kako je, ako zelis da promenis nacin na koji flash gleda na argumente funkcije moraces da predjes na flex i da budzis to sto ti treba

generalno nista ne bi dobio brisanjem
syndrome
Pogledaj ponovo post #20 i shvatices zasto arguments ne duplira memoriju. Barem ne sa kompleksnim podacima. Prosledjivanje by reference (i uopste, referenciranje podataka) upravo tome i sluzi. Nista se ne duplira. Svi pokazuju na isti podatak, ma koliki on bio.
the
^^ drugim rečima, WW ima arguments[0] (nema argumenata) za to što priča. wink.gif
MrSteel
probajte
arguments = new FunctionArguments();
u funkciji

hehe
CODE
function nova(a,b,c:Number):Void {
   arguments = new FunctionArguments();
   trace(arguments + " " + a + " " + b + " " + c);
}


hehe
nemoj WW da se zbunjivas
WhiteWeedow
MrSteel ovde mogao si da stavis bilo sta znaci arguments = x; bas si sad napisao ono sto ja govorim gore ali dobro mozda mi se samo cini, ponistio si argumente koji su pristigli u funkciju, a ovo je skoro ravno delete operatoru nije isto ali skoro.

Bolje znate od mene i to postujem i postovat cu tako da to je to.

Pokusat cu ubuduce da se nezbunjivam smile.gif, tema je bila zanimljiva, meni naravno smile.gif.
Syndrome jasno mi je sad ono.
Ovo je "lo-fi" verzija našeg glavnog sadržaja. Da biste videli punu verziju, sa svim informacijama, formatiranjem ili slikama, molimo vaskliknite ovde.
Invision Power Board © 2001-2013 Invision Power Services, Inc.