Newsgroup: it.comp.www.php
Titolo: Creare metodi a runtime

Esiste in PHP una maniera efficace di definire dei *metodi* istanza a
runtime (come in Ruby o in Javascript)?
Devo generare dinamicamente un numero non noto a priori di setters /
getters. Ho utilizzato con scarso successo create_function (con un codice
da brivido).
// Create getter
eval("\$this->get_{$row['Field']} = create_function('\$this', 'return
\$this->values[\'{$row['Field']}\'];');");
// Create setter
eval("\$this->set_{$row['Field']} = create_function('\$this, \$value',
'\$this->values[\'{$row['Field']}\'] = \$value;');");
che pero' mi da' un puntatore a funzione lambda (anonima), e non un vero
metodo -- che dovrebbe valere per OGNI istanza della classe, e non solo
quella in cui vengono definiti :(
Passare $this come parametro e' una soluzione sporca che potrebbe
funzionare solo sotto PHP 4. PHP 5 mi risponde "Fatal error: Using $this
when not in object context in ..."
TIA
-- 
Somministrazione di lavoro intraanale.

 
Ridefinire __set e __get?
http://it2.php.net/language.oop5.overloading
Oppure qualsiasi altra soluzione, tranne eval!
	Francesco

 codice da brivido).
A cosa ti serve creare questi metodi?
Sei sicuro che non esista un pattern che ti possa venire incontro senza
dover scomodare l'overloading?
-- 
Vuoi distribuire il tuo sito web su CD/DVD?
Prova 
http://www.dwebpro.com/
Vuoi diventare un esperto analista PHP/MySQL?
Vieni a fare uno stage con noi: 
http://www.creativepark.it/stage/

 dover scomodare l'overloading?
uhm.. no. Sto scrivendo un clone leggero dell'ORM ActiveRecord di Rails, ma
mi manca la potenza semantica del Ruby :(
Vedo che si possono usare __call, __set e __get anche sotto PHP4 (non
vorrei perdere la compatibilita'), a patto di avere il PHP compilato
opportunamente, ora devo accertarmi che il mio server disponga di una
versione adatta.


delphine ha scritto:

Potrebbe essere che mi sia sfuggito qualche dettaglio, ma a cosa ti
servono getter e setter? Non è mica Java ;-) La proprietà la crei al
volo assegnandogli uno slot, come in JavaScript:
  class MyClass {
    // vuota
  }
  $obj = new MyClass();
  $obj->Field = $row['Field'];
e la proprietà è direttamente disponibile.
I getter/setter li vedo utili se devono anche
manipolare/convertire/adattare i dati, ma non ho capito se devi fare
anche questo.
Ciao.

 anche questo.
esatto, ho l'esigenza doppia:
- di mascherare l'accesso ai dati, contenuti in realta' in un array membro,
referenziandoli dall'esterno con un nome uguale alla chiave nel dizionario.
- di manipolare "al volo" i dati (se conosci Rails capirai cosa intendo).
Per fare un rapido esempio, supponiamo di avere una colonna:
'created_at' DATETIME NOT NULL
L'oggetto conterra' automaticamente il suo valore in 
$this->values['created_at']
per referenziare il valore dall'esterno usero':
$this->created_at
e per avere la data in formato leggibile:
$this->created_at_human_readable
il getter deve incaricarsi di fare le opportune trasformazioni, in base a
delle convenzioni sui nomi delle variabili (es. il suffisso
'_human_readable')


 '_human_readable')
Questa sintassi a me non piace molto, perche` confonde i nomi delle 
colonne con le opzioni possibili nella classe.
Cosa succede se un utente crea una tabella cosi`:
create table pippo (
 data date,
 data_human_readable varchar(255)
);
o con qualsiasi altra inflessione tu implementi nel tuo codice?
Preferisco altri sistemi, come creare un oggetto per ogni tipo del DB (o 
uno che li gestisca tutti), e scrivere quindi
$this->created_at->human_readable();
Oppure facendo una funzione direttamente nell'oggetto:
$this->human_readable("created_at");
che, tra l'altro, puoi anche potenziare sovraccaricando __call():
...
public function __call($f, $p) {
 if ($f=="human_readable") {
  $obj = new DBData($this);
  return $obj->human_readable($p);
 }
}
...
Ecc. ecc.
Come consiglio generale ti direi di capire e sfruttare bene il linguaggio 
che stai usando (PHP) invece di cercare parallelismi con altri linguaggi 
come Ruby, che ha caratteristiche molto diverse.
Disclaimer: tutto il codice qui sopra e` supportato in PHP5, ma quasi 
sicuramente NON in PHP4, che comunque e` morto.
Disclaimer2: sono andato a memoria con i magic methods. Tratta il suddetto 
come metacodice e vedi il manuale per la sintassi corretta. :)
Bye.