Visualizzazione post con etichetta json. Mostra tutti i post
Visualizzazione post con etichetta json. Mostra tutti i post

giovedì, gennaio 29, 2015

Mongodb su mongolab

Vogliamo aggiornare la nostra splendida applicazione su https://whispering-peak-1284.herokuapp.com/, inserendo una persistenza vera dei dati.

Vi ricordo che i nostri libri sono memorizzati in un array in memoria all'avvio dell'applicazione, eventuali nuovi libri inseriti rimangono solo fino al prossimo riavvio.

La nostra applicazione su heroku deve poter comunicare con un server di base dati, vogliamo ovviamente scegliere mongodb; heroku fornisce come addson (modulo aggiuntivo) la possibilità di far interagire una applicazione ivi installata con una istanza di mongodb ospitata da un'altra società che offre servizi di memorizzazione dati su mongodb, questa società si chiama mongolab.

Purtroppo per poter utilizzare direttamente mongolab da heroku, bisognerebbe fornire la carta di credito anche si decidesse, come noi, di utilizzare una istanza limitata gratuita per scopi di testing e sviluppo.

Pazienza faremo a manina.

Createvi direttamente un account su mongolab, effetuate l'accesso e pigiate sul bottone create new, come mostrato in figura, per creare una nuova base dati.


Nella schermata successiva, selezionate le seguenti opzioni
  • Location: Amazon's EU (Ireland) Region (eu-west-1)
  • Plan: Single-node, Sandbox
  • Database name: bibliotecadb
Premete il bottone create new MongoDB deployment per creare una base dati mongodb dal nome bibliotecadb.


Nella schermata successiva, premete sul link bibliotecadb


Nella prossima schermata troveremo le informazioni di connessione che utilizzeremo sia da robomongo per gestire la nostra base dati sia dall'applicazione residente su heroku.

Nel mio caso l'indirizzo di connessione è ds037601.mongolab.com:37601/bibliotecadb nel vostro caso sarà ovviamente diverso: prendetene nota.

Ora non ci rimane che creare un'utenza di accesso alla base dati appena creata, ce lo dice anche mongolab con questo messaggio terrorizzante A database user is required to connect to this database.  Click here to create e new one : premete sul link click here e inserite le seguenti informazioni nella maschera successiva
  • Database username: biblioteca
  • Database password: biblioteca
  • Confirm password: biblioteca

Premete il bottone create e la nostra base dati è pronta a ricevere istruzione dall'esterno.

Ora eseguite robomongo e create una nuova connessione inserendo i dati di connettività, il nome della base dati e l'utenza definiti precedentemente.




Sostituite il campo address con l'indirizzo assegnato alla vostra base dati.
Il campo name è solo un nome logico che robomango utilizza per memorizzare i dati di una particolare connessione.

Selezionate poi il pannello Authentication e inserite i seguenti dati, coerentemente a quanto fatto in precedenza


Pigiate il bottone Test per verificare la correttezza dei dati di connettività, se non avete fatto errori dovreste ottenere la schermata seguente


Salvate i dati di connessione e siamo ora pronti a connetterci alla nostra base dati su mongolab


Una volta connessi, creiamo una nuova collezione libri: tasto destro su Collections



Tasto destro su Collections/libri ...


Selezioniamo Insert Document e inseriamo le proprietà del nuovo libro da salvare


Ripetiamo il passo precedente per inserire un altro paio di libri e per eseguire una db.libri.find(): tasto destro su Collections/libri e selezioniamo View Documents.

Dovreste ottenere una schermata con la lista dei libri che avete inserito.


Abbiamo dunque creato una base dati utlilizzando mongodb su mongolab, non resta che modificare la nostra applicazione per leggere e scrivere i dati da essa.

Alla prox.
Ivan

martedì, gennaio 27, 2015

MongoDB: operazioni CRUD e Robomongo

MongoDB memorizza i dati nella forma di documenti che non sono altro che coppie di chiavi/valore alla stregua del formato json.
 {  
   nome : 'ivan',                            chiave: valore  
   età: '43',                                chiave: valore  
   linguaggi: ['java', 'javascript']         chiave: valore  
 }  
Tutti i documenti sono memorizzati in collezioni. 

Una collezione è un gruppo di documenti correlati che hanno un insieme di indici condivisi.
Spesso una collezione di mongodb viene considerata alla stregua di una tabella di una base dati relazionale: mi sembra una forzatura visto che i documenti presenti in una collezione non devono avere la stessa struttura.

In mongodb, le interrogazioni (query) vengono effettuate su delle collezioni; possono specificare dei criteri per filtrare i risultati e possono includere una proiezione per ottenere solo determinate coppie chiavi/valore dei documenti ricercati; si possono opzionalmente impostare limiti e criteri di ordinamenti.
Ecco un esempio di query che cerca nella collezione dipendenti quelli che sono maggiorenni e i risultati sono ordinati per cognome in maniera crescente.
   Collezione     Criterio     Ordinamento  
 db.dipendenti.find({età: {$gt: 18}}).sort({cognome: 1})  
In questo esempio, cerchiamo i primi 5 utenti, in ordine alfabetico per nome, che abbiano meno di 50 anni: di questi utenti ci interessa solo il nome e l'indirizzo: la query ritorna comunque la proprietà _id per ogni documento.
 Collezione            Criterio            Proiezione      Ordinamento  Limite  
 db.utenti.find({età: {$lt: 50}}, {nome: 1, indirizzo :1}).sort({nome:1}).limit(5)  
Il metodo find torna sempre un cursore; se eseguito in una shell mongo e il risultato del metodo non viene assegnato ad una variabile, la shell itera i primi 20 risultati mostrandoli a video: un uso programmatico del cursore sarebbe il seguente, tenendo conto che nella shell mongo viene utilizzato un linguaggio di scripting quasi identico a javascript
 var cursore = db.libri.find()  
   
 while(cursore.hasNext()) {  
    printjson(cursore.next())  
 }  
 
 //oppure  
   
 cursore.forEach(printjson)  
Molto intuitivamente: finchè ci sono elementi nel cursore, viene stampanto il prossimo elemento puntato dal cursore stesso, la stampa avviene in formato json.

Per aggiornare un documento esistente, la sintassi è la seguente
 db.libri.update(  
    {  
       titolo: 'la guerra'         
    },  
    {  
       $set {  
          autore: 'Ancora non lo so'  
       }  
    }  
 )  
Con questa istruzione aggiorniamo la proprietà autore del documento la cui proprietà titolo vale 'la guerra'; il metodo update aggiorna solo un documento alla volta, se vogliamo aggiornare più documenti dobbiamo aggiungere l'opzione {multi : true} come terzo parametro.

Per eliminare un documento, la sintassi è la seguente
 Rimuove il libro dal titolo 'la guerra' dalla collezione libri:
   
 db.libri.remove({titolo: 'la guerra'})  
   
 Svuota la collezione libri: 
   
 db.libri.remove({})  
Se volete utilizzare un client mongo più amichevole rispetto alla linea di comando, vi consiglio di scaricare e installare l'applicazione gratuita robomongo .

All'avvio dell'applicazione, create una nuova connessione verso localhost come mostrato in figura


Connettetevi con il tasto connect e avrete la possibilità di eseguire le query in una shell che fornisce anche funzionalità di autocompletamento sintassi.

Il programma è molto intuitivo, non farete fatica ad utilizzarlo come si deve.



Bene, nel prossimo post, saremo pronti a mettere la nostra base dati online per essere accessibile dal mondo intero :)

Alla prox.
Ivan

martedì, dicembre 02, 2014

Impariamo a definire i nostri ravioli .. ehm ... moduli in node.js

Node.js è stato disegnato all'insegno della modularità.
Abbiamo già notato come esista una pletora di moduli utilizzabili da un programma node.js:
basta utilizzare l'istruzione require('nomemodulo') per utilizzare le funzionalità esportate dal modulo.

La piattaforma provvede una serie di moduli inclusi nella distribuzione di base, abbiamo visto ad esempio l'utilizzo del modulo fs o del modulo path

In questo post impariamo a definire i nostri moduli da utilizzare nei nostri programmi, per cercare di programmare utilizzando ravioli e non spaghetti

Una volta definito un modulo, è anche possibile pubblicarlo sul repository ufficiale dei moduli gestiti da npm.

Date un'occhiata alla lista ufficiale di moduli per node disponibili attualmente.

Se vi piace un modulo, basterà eseguire in una shell il comando npm  <nomemodulo> nella cartella radice del progetto che state sviluppando, per poterlo utilizzare con una istruzione di require('nomemodulo') dal vostro codice.

Ad esempio, supponete di aver bisogno della funzionalità di trasformazione dei vostri oggetti json in formato xml: basterà utilizzare il modulo di terze parti che si chiama xml registrato sul repository ufficiale.

Vi posizionate nella cartella del vostro progetto e digitate npm install xml: verrà creata una directory node_modules, all'interno del vostro progettoche contiene i sorgenti del modulo, se un modulo dipende da altri moduli, questi verranno a loro volta scaricati in locale, tutto in maniera semplice e trasparente.

Ogni modulo ufficiale ha una pagina di documentazione come questa in cui ci sono le informazioni su come utilizzarlo.

In questo caso basta scrivere del codice di questo tipo
 var xml = require('xml');  
   
 var xmlString = xml({libri :   
      [  
           {  
                libro: [  
                     {titolo : 'Il signore degli anelli'},   
                     {autore : 'Tolkien'}  
                ],  
           },  
           {  
                libro: [  
                     {titolo: 'Guerra e pace'},  
                     {autore: 'Tolstoj'}  
                ]  
           }  
      ]  
 }, true);  
   
 console.log(xmlString);  
Per ottenere sulla console
 <libri>  
   <libro>  
     <titolo>Il signore degli anelli</titolo>  
     <autore>Tolkien</autore>  
   </libro>  
   <libro>  
     <titolo>Guerra e pace</titolo>  
     <autore>Tolstoj</autore>  
   </libro>  
 </libri>  
I singoli moduli devono essere definiti in un file, il cui nome sarà il nome del modulo, all'interno del file si deve utilizzare una istruzione del tipo module.exports = {}: assegniamo alla proprietà export dell'oggetto globale module un qualsiasi oggetto che definiremo noi, magari una iife per incapsulare dettagli implementativi mediante il meccanismo delle closure.

Facciamo un esempio.
Immaginiamo di implementare un modulo biblioteca che ci permetta di salvare in memoria dei libri e di ottenere la lista attuale dei libri.

Il programma principale utilizza il modulo biblioteca
 var biblioteca = require('./biblioteca');  
   
 biblioteca.inserisciLibro({  
      titolo : "Il signore degli anelli",  
      autore : "Tolkien"  
 });  
   
 biblioteca.inserisciLibro({  
      titolo : "Guerra e pace",  
      autore : "Tolstoj"  
 });  
   
 biblioteca.elaboraLibri(function(error, libri) {  
      if (error)  
           console.log(error.messaggio);  
      else {  
           libri.forEach(function(libro) {  
                console.log("Titolo: " +   
                          libro.titolo +   
                          "- Autore: " +   
                          libro.autore);  
           });  
      }  
 });  
Il modulo biblioteca dovrà essere implementato in un file dal nome biblioteca.js presente nella stessa cartella del file programma.js che rappresenta il programma principale.
 module.exports = (function() {  
      var libri = [],  
          inserisciLibro = function(libro) {  
             libri.push(libro);  
          },  
          elaboraLibri = function(callback) {  
             if (libri.length === 0)  
                callback({messaggio: 'biblioteca vuota'}, null);  
             else  
                callback(null, libri);       
          };  
          
          return {  
             inserisciLibro : inserisciLibro,  
             elaboraLibri : elaboraLibri  
          };  
 })();  
Notate la prima istruzione che assegna a module.exports il risultato di una funzione che viene eseguita immediatamente, tale risultato è un oggetto che espone solo i metodi inserisciLibro ed elaboraLibri.

Notate anche l'utilizzo di una funzione di callback definita in programma.js e passata come argomento a eleboraLibri, tale funzione di callback verrà eseguita solo se non ci sono condizioni di errore (in questo caso rappresentate da una biblioteca vuota).

Ho aggiornato su github il progetto, effettuate un git pull per aggiornare i sorgenti che avete in locale, come mostrato questo post.
Ricordatevi, per il progetto esempio-xml, di posizionarvi nella cartella radice ed eseguire npm install xml per includere il modulo xml nel progetto.

Se avete dubbi e/o domande, commentate!

Alla prox.
Ivan


mercoledì, novembre 26, 2014

Ajax in azione

Con questo post, vi mostrerò come implementare richieste asincrone ad un componente server.

Per rendere l'esempio funzionante, ho creato una piccola applicazione web che risponde ad ogni richiesta che riceve, con la lista di due libri in formato json.

La richiesta partirà in modalità asincrona da questa stessa pagina che risiede su un dominio (blogger.com)  diverso da quello su cui è installata la mia applicazione (herokuapp.com)

Per motivi di sicurezza, non sarebbe possibile fare richieste asincrone in javascript ad un dominio diverso da quello da cui proviene il frammento javascript stesso. (same-origin policy)

Per effettuare una richiesta asincrona ad un server, utilizzando javascript standard, si utilizza un codice di questo tipo, dove ho omesso, per semplicità, eventuali controlli d'errore
  
 var xmlhttp = new XMLHttpRequest();  
 xmlhttp.onreadystatechange=function() {  
   document.getElementById("contenitore").innerHTML= xmlhttp.responseText;  
 };  
 xmlhttp.open("GET","risorsa/?eventualeparametro=valore",true);  
 xmlhttp.send();  

I passi per eseguire una richiesta asincrona sono i seguenti:
  1. istanziare un oggetto con la funzione costruttore XMLHttpRequest
  2. configurare su questo oggetto la funzione di callback che sarà eseguita quando arriverà la risposta dal server
  3. configurare il tipo di richiesta, in questo caso GET, e l'indirizzo della risorsa a cui effettuare la richiesta, che deve risiedere sullo stesso server, concatenendo all'indirizzo eventuali parametri
  4. mandare, in modalità asincrona, la richiesta: la send ritorna subito, non è bloccante. 
  5. appena il server risponde, cambierà lo stato dell'oggetto XMLHttpRequest e dunque verrà eseguita la funzione di callback che, in questo caso, riempirà il nodo che ha id = 'contenitore' con la risposta che è arrivata dal server
Se provassimo ad utilizzare questo frammento di codice utilizzando l'indirizzo reale dell'applicativo che ho sviluppato (https://ajaxjsonpexample.herokuapp.com/),  non otterremmo il risultato sperato, per il noto problema della same-origin policy.

Per ovviare a questa limitazione, nel tempo sono nate una serie di veri e propri hack, il piu' utilizzato dei quali va sotto il nome di jsonp, dove p sta per padding .

In sintesi, si deve fare in modo che la risorsa server ritorni i dati effettivi in formato json, come se fossero il parametro di una funzione:

 callback([{titolo: 'Il signore degli anelli'},{titolo: 'guerra e pace'}])  

La mia applicazione, ritorna al chiamante proprio questa stringa.

Se aggiungiamo alla nostra pagina, dinamicamente, un nodo script il cui attributo src punti all'indirizzo della mia applicazione web, il run time javascript interpreterebbe la risposta del server come una istruzione da eseguire

 callback([{titolo: 'Il signore degli anelli'},{titolo: 'guerra e pace'}])  

Ci basta allora aggiungere una proprietà dal nome callback sull'oggetto globale window, di tipo funzione, che gestisca l'array di libri ricevuti come parametro.

Provate a cliccare il bottone seguente




Ho messo l'implemetazione dell'esempio (codice lato client) su github. Fate riferimento a questo post per capire come fare ad ottenerli sulla vostra macchina.

Se aprite i web tools con F12 e andate sul tab networking e poi script, e cliccate di nuovo il bottone,potrete effettivamente osservare la richiesta fatta al server esterno con la relativa risposta.



In un prossimom post vi parlerò di heroku e di come sia facile pubblicare una nostra applicazione web su questa piattaforma di hosting che supporta già ruby,php,nodejs,java,python,scala,clojure.

L'applicazione web che ho installato su heroku è scritta in java, è costituita da una semplice servlet che scrive direttamente sulla risposta la stringa json che rappresenta l'array dei due libri.

Alla prox.
Ivan

lunedì, novembre 17, 2014

Ma ... funzioni costruttore? senza classe? mah ...

Purtroppo esistono diversi modi per creare un oggetto.

Quello piu' comune è attraverso la notazione json (object literal)

 var automobile = { cilindrata: 1300, colore:'rosso'};  

Lo stesso oggetto possiamo costruirlo utilizzando una funzione costruttore, che non è altro che una funzione invocata tramite l'operatore new. Vi ricorda qualcosa?


 var Auto = function(cilindrata, colore) {  
   this.cilindrata = cilindrata;  
   this.colore = colore;  
 }  
 var automobile = new Auto(1300,'rosso');  

Auto è una funzione costruttore, quando invocata con l'operatore new, this punta all'oggetto che viene appena creato, a cui si agganciano dinamicamente le proprietà cilindrata e colore: anche se non è evidenziato, l'ultima istruzione di una funzione costruttore, quando invocata con il new, ritorna l'oggetto this appena creato.

Cosa succede se ci dimentichiamo di utilizzare l'operatore new?

 var Auto = function(cilindrata, colore) {  
   this.cilindrata = cilindrata;  
   this.colore = colore;  
 }  
 var automobile = Auto(1300,'rosso');  


La funzione non ritorna alcun valore, quindi automobile ha il valore undefined, eseguendo la funzione Auto(1300, 'rosso'), aggiungiamo dinamicamente le due proprietà a this che in realtà punta a window con l'effetto di riempire lo scope global con tante variabili globali!  E' buona norma utilizzare la lettera maiuscola per identificare una funzione di tipo costruttore.

E' utile evidenziare che le due modalità di creazione degli oggetti sono assolutamente equivalenti.
Il concetto di funzione costruttore è stato introdotto per rendere familiare il linguaggio javascript ai programmatori java, ma è fuorviante perchè non esiste il concetto di Classe in Javascript, esiste solo il concetto di oggetto:

 var o1 = new Object();  
 
 var o2 = {};  

Nell'esempio, o1 e o2 sono due oggetti equivalenti. Il primo è costruito con la funzione costruttore Object(), il secondo con la notazione json.

Quindi fatevi un favore, evitate di usarla, la funzione costruttore, se ne puo' fare tranquillamente a meno ;)

Alla prox
Ivan

sabato, novembre 15, 2014

Spaghetti o Ravioli?

Siamo ora pronti a comprendere il codice presentato nel primo post, lo riscrivo qui per comodità

  var modulo = (function() {  
                   var f1 = function() {  
               
                            },  
                       f2 = function() {  
                 
                            },  
                       f3 = function() {  
                 
                            };  
               
                       return {  
                         f1 : f1,  
                         f2 : f2,
                         f3 : f3
                       };   
                })();  
   

Cosa contiene la variabile modulo? Contiene il risultato della esecuzione immediata della funzione dichiarata a destra, tale funzione ritorna il seguente oggetto


 {  
   f1 : function() {},  
   f2 : function() {}  
 }  
   
   

e quindi window.modulo espone le uniche proprietà f1 e f2 che in questo caso sono funzioni.

Le inner function, cioe le funzioni dichiarate all'interno di un'altra funzione, hanno l'importante proprietà di poter accedere alle variabili locali e i parametri dell'outer function anche quando l'outer function ha terminato la sua esecuzione.

Questa caratteristica, chiamata closure, insieme al concetto di  IIFE: Immediate Invocation Function Expression,  acronimo pomposo per descrivere una funzione che viene invocata appena subito dopo la sua dichiarazione, permette di creare degli oggetti che espongono solo le funzioni che vogliamo, nascondendo i dettagli implementativi; ciò ci permette di modularizzare il nostro codice, passando da un codice a spaghetti a un codice a ravioli :)

Facciamo ancora un esempio:

 var biblioteca = (function(nome) {  
        
      var libri = [],  
       
           nomeBiblioteca = nome,  
          
           inserisciLibro = function(libro) {  
               libri.push(libro);  
           },  
          
           getNomeBiblioteca = function() {  
               return nomeBiblioteca;  
           },  
          
           numeroLibri = function() {  
               return libri.length;  
           };  
   
          return {  
            insert : inserisciLibro,  
            getName : getNomeBiblioteca,  
            length : numeroLibri  
          };  
   
 })('civica di milano');  


 biblioteca.insert({titolo:'guerra e pace'});
 console.log(biblioteca.getName());
 console.log(biblioteca.length());

biblioteca è un oggetto, ritornato dalla funzione che viene immediatamente eseguita, espone dunque solo i tre metodi insert, getName, e length.

La variabile locale libri non è accessibile dall'esterno, essendo una variabile locale di una funzione,

I metodi dell'oggetto ritornato, possono ancora accedere alle variabili locali della funzione esterna, anche se la funzione esterna ha già finito la sua esecuzione: notate bene che in questo caso la eseguiamo immediatamente passandole il parametro 'civica di milano'.

Le linee di codice successive, memorizzano il libro dal titolo 'guerra e pace' nell'array libri, che esiste ancora nonostante la funzione precedente ha finito la sua esecuzione, stampano sulla console rispetivamente 'civica di milano' e 1.

Spero che ora non abbiate più dubbi sul potente concetto di closure, che ci permette di definire oggetti complessi nascondendo la loro complessita a chi deve utilizzarli.

Cominciate a utilizzare le IIFE e il vostro codice passerà da un groviglio di spaghetti a dei ravioli gustabili  uno ad uno :).

Alla prox.
Ivan

venerdì, novembre 14, 2014

Json e dintorni

Prima di affrontare il concetto chiave di closure, vediamo dunque di definire correttamente quello di oggetto in javascript.

Javascript non è tipizzato, le variabili dichiarate con la parola chiave var possono contenere numeri,stringhe,booleani (true o false), null e undefined.
I numeri, le stringhe e i booleani sono a tutti gli effetti degli oggetti, visto che hanno anche loro dei metodi, anche se sono oggetti immutabili.

Un oggetto è un contenitore di proprietà, dove  le proprietà, separate dalla virgola, hanno un nome ed un valore.
Una proprietà puo essere rappresentata da qualsiasi stringa, compresa la stringa vuota.
Il valore di una proprietà può essere un qualsiasi valore eccetto undefined

Gli oggetti sono utili per contenere e organizzare i dati, gli oggetti possono contenere altri oggetti e così possono rappresentare facilmente strutture ad albero o graphi.

Il modo standard di rappresentare gli oggetti in javascript è costituito dalle parentesi graffe aperte e chiuse che circondano zero o più coppie nome/valore.

 var oggetto_vuoto = {};  
   
 var dipendente = {  
   nome: "ivan",  
   cognome:"saracino"  
 };  
   
 var volo = {  
   compagnia: "alitalia",  
   numero: 345,  
   partenza: {  
    citta: "roma",  
    orario: "14/11/2014 13:30"  
   },  
   arrivo: {  
    citta: "milano",  
    orario: "14/11/2014 15:00"     
   }  
 };  

Ultimamente si usa il formato JSON (Javascript Standard Object Notation) per lo scambio dati tra compenenti distribuiti: il formato JSON nasce proprio dal linguaggio Javascript.

Per recuperare un valore da una proprietà di un oggetto

   
 // metodo standand di navigazione oggetti  
 volo.partenza.citta // roma  
   
 // metodo alternativo che mette in luce la natura di collezione associativa 
 // di coppie nome/valore  
 dipendente["nome"] // ivan  
   
 //proprieta noon presenti su oggetto  
 dipendente.nonesisto // undefuned  
   
 //tentativo di accedere a proprietà di proprietà inesistenti  
 dipendente.nonesisto.proprieta // eccezione a run time  

Per scrivere le proprietà di un oggetto

 // aggiornamento di una proprietà esistente  
 dipendente.nome = "ciccio";  
   
 // se una proprietà non esiste, viene creata  
 // dinamicamente!  
 dipendente.età = 43  

Le variabili che contengono gli oggetti sono dei puntatori agli oggetti in memoria.

Quando passiamo un oggetto come parametro, il passaggio del parametro è per copia  ( qui sono in disaccordo col buon Douglas Crockford che dice che il passaggio è by reference) come dimostrato dal seguente frammento di codice:

 var x = {p : 1};  
   
 var y = x;  
   
 y.p = 2;  
   
 x.p vale 2, stiamo modificando lo stesso oggetto   
 tramite lo stesso puntatore  
   
   
 definiamo una funzione che modifica la proprietà  
 di un parametro  
   
 var f = function(par) {par.p = 3};  
   
 invochiamo la funzione passando l'oggetto x  
   
 f(x);  
   
 x.p vale 3, nella funzione usiamo la copia   
 del puntatore x per modificare lo stesso oggetto in memoria  
   
 cerchiamo di cambiare l'oggetto puntato da par  
   
 var f = function(par) {par = {p:4}};  
   
 invochiamo nuovamente la funzione passando l'oggetto x  
   
 f(x);  
   
 x.p vale ancora 3, par è una copia del puntatore x,   
 copia che muore quando finisce la funzione f,  
 x punta all'oggetto originale  

In effetti il passaggio dei parametri è identico al linguaggio Java.

Ci sono altre considerazioni da fare sugli oggetti, ma credo sia opportuno dedicarci un post apposito.

Alla prox.
Ivan