2015-02-25 13 views
11

Sto tentando di utilizzare accessors sintetizzati su un componente su Lucee (anche se questo problema sembra essere lo stesso anche in ColdFusion).Comportamento imprevisto con accessors = true su un componente

codice

Repro:

// Person.cfc 
component accessors=true { 

    property firstName; 
    property lastName; 

    function init(firstName, lastName){ 
     variables.firstName = arguments.firstName; 
     variables.lastName = arguments.lastName; 
    } 

} 

E il codice chiamante:

// person.cfm 
person = new Person("Abigail", "Bowen"); 
writeDump(person); 

Avviso come sto non utilizzando le funzioni di accesso sintetizzati qui, sto semplicemente impostando i valori degli argomenti in all'omonimo variabili con scope variabili.

Tuttavia quando si esegue questo codice, vedo questo:

Dump output showing properties

Nota come le proprietà sono state popolate. Non c'è alcun problema con questo, ma chiaramente non capisco come dovrebbe funzionare il flag accessors. Pensavo che fosse semplicemente inteso a sintetizzare alcuni metodi di accesso per me (che ha), ma questo è tutto.

noti inoltre che se modifico la definizione CFC per non di accesso impostata su true, quindi il dump mostra questo:

Dump with no properties

Quindi niente di accesso sintetizzati (come previsto), ma anche ora il le proprietà non vengono nemmeno visualizzate (con i valori delle variabili-ambito o no).

Non capisco davvero questa combinazione di "proprietà" e impostazione degli accessor? Sicuramente l'impostazione degli accessor dovrebbe avere un impatto solo sulla creazione di quei metodi di accesso?

Se stavo vedendo solo questo su una delle piattaforme, probabilmente lo metterei in una situazione inimmaginabile di come writeDump() interpreta le definizioni di proprietà. Ma il comportamento è lo stesso su ColdFusion 11, quindi sembra davvero che ci siano delle differenze nel comportamento che non sto ottenendo.

Qualcuno può spiegarlo? Ci sono documenti che lo spiegano? Se no ... ehm ... perché no?

La mia preoccupazione di fondo qui è che i valori delle proprietà non vengono memorizzati "correttamente" e potrebbero causare problemi una volta che implemento più del codice.

UPDATE: Almeno su ColdFusion, sembra essere solo un cambiamento nel comportamento writeDump() s', perché se ci sono getter per le proprietà (o meno il flag accessors è impostato) allora i valori delle proprietà cominciano mostrando nella discarica. Questo non è il caso di Lucee, quindi c'è ancora un punto interrogativo lì.

Per motivi di completa divulgazione, questa domanda è un riepilogo di una domanda che ho anche chiesto sul mio blog ("CFML: trying to understand accessors"). La duplicazione è intenzionale in quanto il mio blog riceve un pubblico diverso da quello di questo sito.

risposta

10

Senza accessors=true, le dichiarazioni property sono solo metadati.

Con accessors=true, le dichiarazioni property innescano la generazione di getter/setter e quindi una property è sia un elemento variables portata e una coppia di metodi.

nel costruttore, si assegna alle voci portata variables - che sarebbe lo stesso che utilizzare i setter generati - e quando CFML discariche componente, vede il property metadati e le getter generati e quindi visualizza la valuta quelle proprietà (dato che può facilmente e tranquillamente chiamare i getter generati).

+1

Sì, questo è ciò che sembra (vedere il mio aggiornamento). Il comportamento di Lucee è leggermente in disaccordo con quello di ColdFusion. Immagino che Lucee cerchi l'impostazione * e * i metodi; CF cerca solo i metodi. E la differenza è interamente nel comportamento di scarico, non in qualsiasi altra cosa. –

+0

Si tratta solo di un comportamento del costruttore CF9? In CF9, init() è diventato un vero costruttore in quanto, se ne hai uno, viene chiamato automaticamente quando usi la nuova parola chiave, la stessa di Java. La stessa cosa dovrebbe accadere se si rinomina init() in Person(). Se voi ragazzi foste corretti, accadrebbe anche se avete usato qualche altro nome di funzione - che non è così. Succede solo quando CF è in esecuzione come costruttore. – ialexander

2

Questo è venuto con ACF9. Fino ad allora la definizione nei documenti di proprietà era corretta: le dichiarazioni cfproperty sono solo i metadati. (Vedi discarica (getMetaData())

In ACF9 questo non era più completamente corretto per 3 motivi:.

  1. Con accessors=true un getter e setter viene generato per ogni proprietà e quelle di accesso di lettura e scrittura allo scope delle variabili. Cfproperty non è più solo metadata, ma ha un effetto diretto sul comportamento dell'istanza.Mi piace pensarlo come la versione CF delle proprietà OO reali (introdotte per caso)

  2. c L'implementazione fdump modifica il suo comportamento in base alle dichiarazioni di proprietà. Se property name; è definito e il metodo getName() esiste (generato o implementato), viene aggiunto alla sezione delle proprietà del dump.

  3. Gli attributi di proprietà controllano l'ORM.

Da quando ho avuto modo di conoscere queste caratteristiche, io disegno tutti i miei CFC (pubbliche) di guardare a destra quando scaricato, ad esempio. Io uso solo la dichiarazione di proprietà (+ getter) quando voglio renderlo visibile. Inoltre, è possibile implementare i metodi che vengono chiamate solo dalle discariche e costano niente sulla esemplificazione:

struct function getDebug(){ 
    var x = doSomethingExpensive(); 
    return { "Foo":f, "Bar":b, "Baz":x }; 
} 

//or for a user iterator 
string function getName(){ 
    return qUsers.name[index]; 
} 

Alcuni avvertimenti Lo so:

  • ACF chiama sempre i getter dalle discariche, mentre in Railo/Lucee viene mostrato il valore dall'ambito delle variabili. Pertanto, gli esempi sopra riportati (getDebug() e getName()) non funzionano su Railo/Lucee.
  • Se il getter non è pubblico o genera un errore, il dump mostra una stringa vuota per la proprietà (non è sicuro qui, forse la proprietà è invece mancante).
  • Le dichiarazioni di proprietà nei CFC estesi vengono ignorate. Questo mi ha dato un po 'di mal di testa nelle entità ORM che usano l'ereditarietà, perché non sei autorizzato a dichiarare una proprietà due volte. Pertanto, non è possibile mostrare una proprietà definita in un CFC di base.
  • Railo/Lucee sembra ignorare i tipi di proprietà. Tutti gli accessor accettano e restituiscono solo stringhe (vedi getMetaData()).
  • Minore: in ACF quando si attiva la funzione di accesso, ma si disattiva getter e setter per una proprietà: property name="user" getter="false" setter="false"; è ancora visibile nella discarica: deve essere nascosto.
Problemi correlati