Asszociatív tömb

Fórumok

function main()
local hash:=simplehashNew()

    hash:set("próba","szerencse")
    hash["vanaki"]:="forrón szereti"
    
    ? hash["próba"]+="!" // szerencse!
    ? hash:get("vanaki") // forrón szereti

Hozzászólások

Külön kiraktam ide a simplehash osztály forrását. Érdemes elolvasni, mert 100-nál kevesebb sorból megérthető belőle a hash tábla működése. Sőt, az osztálydefiníció nélküli tényleges algoritmus (a lényeg) csak 20 sor.

--
CCC3

Ha már úgyis piszkáltam az indexelést:

    
    x:="Próba szerencse"
    ? x[1] //kiírja: P
    ? x[2..4] //kiírja: rób
    ? x[..4]  //kiírja: Prób
    ? x[4..]  //kiírja: ba szerencse

    //nem állhat a baloldalon
    x[1]:='X'  //kivételt dob

Az indexelés figyel az indexhatárokra, és kivételt dob túlnyúláskor. A szeleteknél a túlnyúlás üreset ad (mint a left,right,substr-nél). Karakter- és byte-stringekre is működik.
--
CCC3

Tök jó. Ennek örömére ezt rögtön fel is használtam a ccc-contribban, tehát a ccc3winter könyvtár csak a legfrissebb CCC-vel fog fordulni. Akinek ez nem felel meg, használjon ccc3ext-et, abba még nincs átvezetve ez a változtatás.

w

ui: nem fog szintaktikai káoszt okozni?

Ezt a két kifejezést nézzük:


    a[x]
    a[x]:=y

Hol lesz érzékelhető a különbség az array és a hash esetek között? A szintaktikai elemzőben nincs különbség. A nyelvtani elemzőben sincs. A fordítóban (kódgenerátorban) sincs! Csak az a primitív változik, ami a kifejezést kiértékeli. Tehát kifejezetten egyszerű ügyről van szó.

Bonyolultabb eset a string szeletek képzése: str[x..y]. Ennél a szintaktikai elemzővel kezdődően minden változott, pedig esetleg azt gondolnád, hogy ez az egyszerűbb. Itt viszont a speciális szintaktika biztosítja az egyértelműséget.

Ilyen esetekben, amikor a fordító változik, úgy szoktam eljárni, hogy az összes (!) meglevő programomat (ami az újításokat még nem tartalmazza) lefordítom a régi és az új fordítóval, és ellenőrzöm, hogy a generált C++ kód egyezik-e. Egyezik.

--
CCC3

Igen, pontosan ez az. Az a[x] mostantól kezdve megteheti, hogy idxr-t generál, meg hogy üres stringet ad vissza. De azt gondolom, hogy a CCC eddig is elég sok mindenben megkövetelte a fegyelmet a programozótól, és személy szerint úgy vélem, hogy ez sokkal jobb, mint arra nevelni a programozót, hogy 'írjad csak, majd a compiler úgyis szól, ha valami nem jó'.

w

Tévedés. Az a[x] nem tud üres stringet adni. A túlindexelés errort eredményez, normálisan pedig 1 karaktert ad.
--
CCC3

Az a[x] mostantól kezdve megteheti, hogy idxr-t generál

A fordító etekintetben egyáltalán nem változott, tehát most is pontosan ugyanazt az idxr-es kódot generálja, mint korábban. Nézzük ezt a példát:


function main()
local h:=simplehashNew()
local x:=1
    h:set("key","Hopp")
    ? {1,2,3}[x]              //1. eset, kiírja: 1
    ? h["key"]                //2. eset, kiírja: Hopp
    ? "próba szerencse"[x]    //3. eset, kiírja: p

Ez a program a 10 évvel ezelőtti CCC fordítóval ugyanúgy lefordul és összelinkelődik, mint a mostanival, feltéve, hogy a linker talál valahol egy (akármilyen) simplehashNew függvényt.*

A változás az idxr-en belül történt. Korábban a 2. és 3. eset runtime errort okozott, az új idxr viszont kezeli ezeket az eseteket is. Szintaktikai káoszról tehát szó sem lehet.

A 2. esetnél felvethető, hogy mi legyen az eredmény, ha egy kulcshoz nincs érték rendelve: runtime error vagy NIL. Úgy gondoltam, hogy jobb a NIL.

A 3. esetnél kérdéses lehet, hogyan kezeljük azt az esetet, amikor x nincs az [1,len(string)] intervallumban. Úgy gondoltam, az a logikus, ha runtime error-t ad. Tehát az eredmény nem lehet üres string, hanem mindig pontosan egy hosszúságú string (karakter), vagy error.

Egész más dolog a string szelet: x[i..j]. Itt bővült a szintaktika is, a nyelvtan is, a kódgenerátor is. A string szeletek a left, right, substr-hez hasonlóan működnek, pl.


    substr(x,i,j-i+1)==x[i..j]

feltéve, hogy i>=1 és j>=i. A szeleteknél azt gondoltam logikusnak, ha a túlnyúlás nem okoz errort, hanem az előbbi függvényekhez hasonlóan működik. Pl.


    substr("abc",2,5)=="abc"[2..6]=="bc"

*Megjegyzés: Nincs kizárva, hogy a példaprogram a Clipper 5.2-vel is lefordulna. Ha a string literálok helyén változó állna, akkor bizonyosan. Persze a Clipper 5.2 nem tudná értelmesen futtatni a példaprogramot.