2013-07-09 12 views
6

Ok, penso che sia quasi impossibile. Ma tuttavia: è possibile sapere all'interno di una chiamata di metodo se il metodo è stato chiamato come parte di una chiamata di funzione?Scopri se un argomento di funzione fa parte di una funzione chiama

Esempio (e la mia chiamata di funzione reale):

HDMExpressionSQLSelectBuilder *sb = [[[HDMExpressionSQLSelectBuilder alloc] init] autorelease]; 
[sb orNestedWhere:[sb where:@"wheraCoumnB" equals:@"whereBEqualValue"], [sb where:@"wheraCoumnB" equals:@"sth"], nil]; 

Ci sono due cose che accadono da qui in poi:

  • Gli argomenti vengono valutati in qualsiasi ordine (in cui ordine non è specificato in C standard e cambia tra i compilatori e le impostazioni )
  • Anche se questo dovrebbe essere ovvio per ogni programmatore: Le funzioni interne di sono valutati prima

Ora voglio sapere ad esempio all'interno di questo metodo di chiamata ...

[sb where:@"wheraCoumnB" equals:@"whereBEqualValue"] 

.. che è stato chiamato come parte di un argomento di una funzione.

Possibile? Magia nera?

Prima di venire e dire che sto facendo male, e avrei dovuto risolvere il mio codice: io sostengo che ho uno dei rari casi in cui si farà senso di sapere cosa del genere. Sto scrivendo un generatore di query e questo faciliterebbe notevolmente l'uso di condizioni nidificate. Altrimenti dovrei fare qualche sciocco nidificatoAndBegin e poi nestedAndEnd per implementare parentesi, e così via. In questo caso sarebbe strano, il mio generatore di query è basato sull'albero e non vorrei farlo (diversamente dai costruttori di query di giocoleria di stringa, tutto ciò che sarebbe necessario è mettere il nodo per l'espressione logica in posizione).

Aggiornamento

Quindi questo non è ovviamente possibile. Per coloro che sono interessati a come ho lavorato su questo per il mio particolare problema: l'ho fatto in modo che tutte le chiamate alle funzioni siano rimandate, quindi le chiamate a una funzione del mio generatore di query mettono un oggetto di richiamo del metodo con argomenti di funzione a un elenco di chiamate . Non esegue alcun codice di metodo in quel momento. Ogni oggetto di chiamata ha un ID di sequenza di autoincremento, quindi so quando una funzione è stata valutata. Ora nelle funzioni nestedEnd etc (quindi quelle funzioni di cui trattava la mia domanda) Controllo se l'ID della sequenza degli oggetti di richiamo memorizzati corrisponde all'indice degli argomenti della chiamata di funzione. In caso contrario, questo è il momento giusto per riordinarli.

L'analisi sintattica e la fase di costruzione delle query viene quindi rinviata a utente chiama effettivamente il metodo query() (o AST() per ottenere l'albero di espressione).

risposta

3

No, non esiste un modo (pratico) per farlo.

Si potrebbe, in teoria, aggiungere del codice nel metodo che legge i simboli di debug dal proprio binario, ispeziona il registro dei collegamenti e quindi utilizza tali informazioni per capire il sito di chiamata, carica il codice sorgente da qualche altra parte, e calcola il mapping, analizza il codice sorgente e capisce che viene chiamato come descrivi.

+0

Credo che questa sia la risposta corretta, ma forse qualcuno sa di una soluzione fattibile. Altrimenti probabilmente aggiungerei qualche tipo di registro delle transazioni, che invertirà le ultime modifiche delle funzioni interne e le riapplicherà nell'ordine corretto al momento in cui viene chiamata la funzione esterna.Ma sfortunatamente ciò significherebbe spezzare alcune possibilità di validazione per la costruzione della query. – benjist

+0

È possibile passare anche selettori e argomenti. –

+0

ha, forse è così. Potrei, invece di costruire direttamente l'albero, raccogliere tutte (copie) di argomenti e selettori. e applicarli nell'ordine corretto quando viene richiesta la stringa di query (incluso il controllo della sintassi, anche se in un secondo momento) – benjist

Problemi correlati