2012-02-16 9 views
11

Quindi, dato che ho un istanza di questo componente:Come determinare il contesto in cui si trova un oggetto ColdFusion?

foo.cfc

<cfcomponent> 
    <cffunction name="locateMe"> 
    <cfreturn "I don't know where I live!"> 
    </cffunction> 
</cfcomponent> 

E, questo altro componente, fooParent.cfc:

<cfcomponent> 
    <cfset this.foo = createObject("component", "foo")> 
</cfcomponent> 

Diciamo che creare istanze di "foo" in diversi modi:

<cfset myStruct = {}> 
<cfset myStruct.foo = createObject("component", "foo")> 

<cfset myFoo = createObject("component", "foo")> 

<cfset myFooParent = createObject("component", "fooParent")> 

<cfoutput> 
#myStruct.foo.locateMe()#<br> 
#myFoo.locateMe()#<br> 
#myFooParent.foo.locateMe()#<br> 
</cfoutput> 

Come previsto, th è uscite:

I don't know where I live! 
I don't know where I live! 
I don't know where I live! 

Quello che voglio sapere è, cosa posso possibilmente fare all'interno foo.cfc che mi dirà qualcosa (qualsiasi cosa!) sul contesto in cui viene invocato? Dal momento che tutto alla fine vive in (almeno) un ambito di qualche tipo, e tutti gli ambiti sono una specie di oggetto, quello che sto dicendo è che mi piacerebbe davvero un modo per determinare l'oggetto contenitore, all'interno di un dato oggetto istanziato. Infine, un modo di costruire foo.cfc modo che qualcosa di simile potrebbe essere la mia uscita, dal mio frammento di esempio precedente:

I live within a "class coldfusion.runtime.Struct" instance! 
I live within a "class coldfusion.runtime.VariableScope" instance! 
I live within a "component cfjunk.fooParent" instance! 

Quando ciascuno di questi valori potrebbe essere determinato esaminando il risultato di passare getMetaData reale contenente riferimento all'oggetto.

Aggiornamento Come suggerito da Micah nei commenti, ho aggiunto il tag "Java" a questo, poiché sospetto che potrebbe essere corretto in quanto la soluzione potrebbe risiedere nell'uso di Java per l'introspezione.

Aggiornamento

Piuttosto che lasciare questo come quello che sembra essere una discussione puramente accademica, mi permetta di spiegare il motivo per cui ho bisogno di questo.

sto usando CFWheels ORM con include tornare riferimenti ai miei dati in questo modo:

var user = model("User").findOne(where="id=123", include="AuthSource", returnAs="object"); 

questo tornerà a me un oggetto che io posso fare riferimento in questo modo:

user.id // property of the "User" model 
user.reset() // method on the "User" model 
user.AuthSource.id // property of the "AuthSource" model 
user.AuthSource.authenticate(password) // method on the "AuthSource" model 

Ora, all'interno del mio metodo "AuthSource.authenticate", vorrei conoscere l'oggetto "Utente" in cui sono contenuto. In caso contrario, io finisco per dover chiamare la funzione come questo, invece:

user.AuthSource.authenticate(user, password) // note the redundancy in the use of "user" 

dovrei essere in grado di fare affidamento sul fatto che sto chiamando il metodo sul modello AuthSource attraverso l'oggetto d'uso e in realtà leggere da quell'oggetto all'interno di quel metodo.

+0

Ottima domanda. Mi chiedo se JAVA potrebbe avere alcune funzioni di introspezione per determinare questo genere di cose. Forse potresti ampliare la tua domanda aggiungendo un tag java. – Micah

+0

Perché il downvote casuale su questa domanda? Che strano ... –

risposta

4

È passato molto tempo da quando ho fatto coldfusion, quindi perdona il mio pseudocodice, ma penso che ciò che si fa normalmente in questo tipo di istanze, è che il genitore invii una copia di sé al bambino, quando istanzia il bambino. Questo è usato in molti schemi di progettazione OOP in cui due oggetti devono comunicare tra loro in entrambi i modi, non solo i metodi di chiamata genitore sul bambino.

modo la classe bambino sarebbe stato definito come qualcosa di simile a questo:

<cfcomponent> 
    <cffunction name="init"> 
    <cfargument name="parentParam" required="yes" type="object"> 
    <cfset this.parent = parentParam > 
     <cfreturn this> 
    </cffuncton> 
    <cffunction name="locateMe"> 
    <cfreturn "I belong to #this.parent.className# !"> 
    </cffunction> 
<cffunction name="doOtherStuff"> 
    <cfreturn "I do stuff with my parent: #this.parent.className# !"> 
    </cffunction> 
</cfcomponent> 

e poi quando lo si utilizza ...

<cfset myParent.child = createObject("component", "Object").init(myParent) /> 
#myparent.locateMe()# 
#myparent.doOtherStuff()# 

parentParam sarebbe un parametro richiesto in un metodo costruttore chiamato "init", quindi il bambino ha sempre un riferimento al suo genitore. Quindi tutti i tuoi metodi possono fare uso di questo.parent per fare cose con esso. Nel mio esempio di codice, faccio # this.parent.className # ma non ho idea che gli oggetti coldfusion abbiano una tale proprietà. Probabilmente puoi usare la riflessione o la meta-programmazione di qualche tipo per fare la stessa cosa.

Si prega di notare: da quanto ho capito, ColdFusion non ha il supporto per i costruttori costruito in, quindi sto mostrando è una norma comunitaria best practice da questo sito:

http://www.iknowkungfoo.com/blog/index.cfm/2007/8/22/Object-Oriented-Coldfusion--1--Intro-to-Objectcfc

Sono scusa stai facendo la colfusione dal modo in cui ...;)

+0

Sì, tenere traccia manualmente di un riferimento all'oggetto contenitore è stato il mio primo pensiero. Speravo che potesse esserci una soluzione diversa da quella, comunque. Aspetterò un po 'e vedrò se qualcun altro suona con un approccio diverso. Grazie, e CF non è poi così male! –

+0

Uno sfortunato risultato di questo approccio è che cfdumps del tuo oggetto diventano loop infiniti. :( –

+0

ah che ha senso, perché ogni oggetto ha un riferimento all'altra – fregas

0

Ho rimosso tutti i precedenti in quanto sembrava non essere utile. Seguendo i tuoi commenti successivi, il seguente è un suggerimento che credo possa essere più in linea con ciò che stai mirando a fare.

// Object 
<cfcomponent displayname="Object"> 
    <cffunction name="init"> 
     <cfargument name="username" type="string"> 
     <cfscript> 
      variables.username = arguments.username; 
      variables.authSource = CreateObject('component','AuthSource').init(); 
     </cfscript> 
     <cfreturn this> 
    </cffunction> 
    <cffunction name="authenticate"> 
     <cfargument name="password" type="string"> 
     <cfreturn variables.authSource.authenticate(variables.username,arguments.password)> 
    </cffunction> 
</cfcomponent> 

<cfcomponent displayname="AuthSource"> 
    <cffunction name="init"> 
     <cfreturn this> 
    </cffunction> 
    <cffunction name="authenticate"> 
     <cfargument name="username" type="string"> 
     <cfargument name="password" type="string"> 

      .... DO STUFF ... 

     <cfreturn ...> 
    </cffunction> 
</cfcomponent> 

<cfscript> 
    objUser = CreateObject('component','Object').init('SomeUserName'); 
    // Authenticate 
    objUser.authenticate('SomePassword'); 
</cfscript> 

In questo modo, AuthSource non ha bisogno di conoscere l'oggetto padre, però allo stesso autenticazione volta che qualcuno non ha bisogno di passare ancora il nome utente. L'oggetto (oggetto padre) ha un metodo wrapper per l'autenticazione che aggiunge nel nome utente.

Si tratta di ulteriore assistenza?

+0

Apprezzo la risposta, ma fondamentalmente la tua risposta è "Non è una buona idea provare a fare quello che stai chiedendo". Potresti avere ragione, ma non è davvero una risposta alla domanda.Lo stesso con il modo in cui potrei cambiare il mio vero esempio: so che posso cambiarlo per farlo funzionare, ma non è proprio quello che è in discussione. Forse è ancora un po 'una domanda accademica, dopo tutto. –

+0

Riesco a vedere un uso per quello che state cercando - Potrei usare lo stesso nel progetto al momento sto lavorando. Il modo in cui ho lavorato intorno è passare l'oggetto genitore al figlio, tuttavia questo come detto produce riferimenti circolari che sono problematici durante la serializzazione e ha portato a richiedere metodi per continuare a definire e indefinendo i riferimenti dell'oggetto genitore. Potrebbe aggiornare l'esempio sopra per illustrare anche se finirà abbastanza simile a quello pubblicato da @fregas –

+0

Non sono davvero preoccupato di cosa devo fare per aggirare il problema nel mio ultimo esempio: è piuttosto facile. È più una questione tecnica sull'opportunità o meno di aggirarla, o se ci sia qualche modo di fare il lavoro tecnico specifico per trovare il contesto di un dato oggetto all'interno di quell'oggetto. Probabilmente è meglio focalizzare meno sull'esempio successivo e più sul primo (foo.locateMe() etc ....). –

0

So che questo non è rilevante in questo momento, ma la prossima versione di CF (Zeus) ha una funzione per fare questo http://blogs.adobe.com/coldfusion/2011/12/19/coldfusion-zeus-potr-callstack/.

+0

In realtà, lo stack di chiamate è diverso da quello che sto chiedendo. Nel mio esempio, ognuna delle tre chiamate a foo.locateMe() proviene tutte dalla stessa posizione nello stack di chiamate, nonostante tutto sia contenuto in oggetti diversi. Questo perché lo stack di chiamate si riferisce al percorso di esecuzione (catene di chiamate di funzioni), piuttosto che all'organizzazione degli oggetti in memoria. –

Problemi correlati