Precedente: , Su: Accedere alla tabella simboli   [Contenuti][Indice]


17.4.10.3 Creare e usare valori nascosti

Le routine in questa sezione permettono di creare e rilasciare valori nascosti. Come gli scalar cookie, in teoria i valori nascosti non sono necessari. Si possono creare numeri e stringhe usando le funzioni descritte in Funzioni per creare valori. Si possono poi assegnare quei valori a delle variabili usando sym_update() o sym_update_scalar(), come si preferisce.

Tuttavia, si può comprendere l’utilità di avere dei valori nascosti se si pone mente al fatto che la memoria di ogni valore di stringa deve essere ottenuta tramite gawk_malloc(), gawk_calloc() o gawk_realloc(). Se ci sono 20 variabili, e tutte hanno per valore la stessa stringa, si devono creare 20 copie identiche della stringa.112

Chiaramente è più efficiente, se possibile, creare il valore una sola volta, e fare in modo che gawk utilizzi quell’unico valore per molte variabili. Questo è ciò che la routine in questa sezione permette di fare. Le funzioni sono le seguenti:

awk_bool_t create_value(awk_value_t *valore, awk_value_cookie_t *risultato);

Crea una stringa o un valore numerico nascosti, da valore, in vista di un successivo assegnamento di valore. Sono consentiti solo valori di tipo AWK_NUMBER, AWK_REGEX ed AWK_STRING. Ogni altro tipo è rifiutato. Il tipo AWK_UNDEFINED potrebbe essere consentito, ma in questo caso l’efficienza del programma ne soffrirebbe.

awk_bool_t release_value(awk_value_cookie_t vc);

Libera la memoria associata con un value cookie ottenuto mediante create_value().

Si usano i value cookie in modo dimile a quello con cui si usano gli scalar cookie. Nella routine di inizializzazione dell’estensione, si crea il value cookie:

static awk_value_cookie_t answer_cookie;  /* static value cookie */

static void
inizializza_estensione()
{
    awk_value_t value;
    char *long_string;
    size_t long_string_len;

    /* codice precedente */
    …
    /* … riempire long_string e long_string_len … */
    make_malloced_string(long_string, long_string_len, & value);
    create_value(& value, & answer_cookie);    /* creare cookie */
    …
}

Una volta che il valore è creato, si può usare come valore per un numero qualsiasi di variabili:

static awk_value_t *
do_magic(int nargs, awk_value_t *risultato)
{
    awk_value_t new_value;

    …    /* come in precedenza */

    value.val_type = AWK_VALUE_COOKIE;
    value.value_cookie = answer_cookie;
    sym_update("VAR1", & value);
    sym_update("VAR2", & value);
    …
    sym_update("VAR100", & value);
    …
}

Usare value cookie in questo modo permette di risparmiare parecchia memoria, poiché tutte le variabili da VAR1 a VAR100 condividono lo stesso valore.

Ci si potrebbe chiedere, “Questa condivisione crea problemi? Cosa succede se il codice awk assegna un nuovo valore a VAR1; sono modificate anche tutte le altre variabili?”

Buona domanda! La risposta è che no, non è un problema. Internamente, gawk usa un contatore dei riferimenti alle stringhe. Questo significa che molte variabili possono condividere lo stesso valore di tipo stringa, e gawk mantiene traccia del loro uso. Quando il valore di una variabile viene modificato, gawk semplicemente diminuisce di uno il contatore dei riferimenti del vecchio valore, e aggiorna la variabile perché usi il nuovo valore.

Infine, come parte della pulizia al termine del programma (vedi la sezione Registrare una funzione exit callback) si deve liberare ogni valore nascosto che era stato creato, usando la funzione release_value().


Note a piè di pagina

(112)

I valori numerici creano molti meno problemi, in quanto richiedono solo una variabile C double (8 byte) per contenerli. Naturalmente, valori di tipo GMP ed MPFR usano molta più memoria.


Precedente: , Su: Accedere alla tabella simboli   [Contenuti][Indice]