2013-07-09 13 views
6

OK, myślę, że jest to prawie niemożliwe. Niemniej jednak: Czy jest możliwe poznanie wewnątrz wywołania metody, jeśli metoda została wywołana jako część wywołania funkcji?Dowiedz się, czy argument funkcji jest częścią wywołania funkcji

Przykład (a moje rzeczywiste wywołanie funkcji):

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

Są dwie rzeczy dzieją się stąd na:

  • Argumenty są oceniane w dowolnej kolejności (w których kolejność nie jest przepisowym w standardzie C i zmienia się między kompilatorami a ustawieniami )
  • Mimo że powinno to być oczywiste dla każdego programisty: Wewnętrzne funkcje są oceniano przed

Teraz chcę wiedzieć, na przykład wewnątrz tej metody wywołania ...

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

.. że nazywano go jako część argumentu funkcji.

Możliwe? Czarna magia?

Zanim przyjdziesz i powiesz, że robię to źle, i powinienem naprawić mój kod: Twierdzę, że mam jeden z nielicznych przypadków, w których sensowne jest poznanie takiej rzeczy. Piszę konstruktora zapytań, a to znacznie ułatwi korzystanie z warunków zagnieżdżonych. W przeciwnym razie musiałbym zrobić trochę głupiego zagnieżdżonegoAndBegin, a później zagnieżdżonegoAndEnd w celu zaimplementowania nawiasów i tak dalej. Byłoby to niezręczne w tym przypadku, mój konstruktor kwerend jest oparty na drzewach i nie chciałbym tego robić (w przeciwieństwie do konstruktorów kwerend żonglujących żonglerami wszystko, czego wymagałoby wprowadzenie węzła dla wyrażenia logicznego w miejscu).

Aktualizacja

Więc to nie jest zaskoczeniem to możliwe. Dla tych, którzy są zainteresowani, jak to obejść dla mojego konkretnego problemu: Zrobiłem to tak, że wszystkie wywołania funkcji są odłożone, więc wywołania funkcji mojego konstruktora zapytań umieszczają obiekt wywołania metody z argumentami funkcji do listy wywołań . W tym czasie nie wykonuje żadnego kodu metod. Każdy obiekt wywołania ma identyfikator sekwencji automatycznej, więc wiem, kiedy funkcja została oceniona. Teraz w funkcji nestedAnd itp. (Czyli o funkcjach, o które chodziło moje pytanie) sprawdzam, czy identyfikator sekwencji przechowywanych obiektów wywołania odpowiada indeksowi argumentu wywołania funkcji. Jeśli nie, to jest odpowiedni czas, aby zmienić ich kolejność.

Kontrola składni i faza budowania zapytań są następnie odraczane, dopóki użytkownik faktycznie nie wywoła metody query() (lub ast(), aby uzyskać drzewo wyrażeń).

Odpowiedz

3

Nie, nie ma (praktycznego) sposobu, aby to zrobić.

Teoretycznie, możesz dodać kod w swojej metodzie, który odczytuje symbole debugowania z pliku binarnego, sprawdza rejestr linków, a następnie wykorzystuje te informacje do ustalenia strony wywołania, ładuje kod źródłowy z innego miejsca, i wylicza mapowanie, analizuje kod źródłowy i określa, że ​​jest on wywoływany w trakcie opisywania.

+0

Wierzę, że to jest poprawna odpowiedź, ale być może ktoś wie o możliwym obejściu. W przeciwnym razie prawdopodobnie dodałabym jakiś dziennik transakcji, który odwróciłby ostatnie zmiany przez wewnętrzne funkcje i ponownie zastosował je w odpowiedniej kolejności w momencie wywołania funkcji zewnętrznej.Ale niestety oznaczałoby to zerwanie z pewnymi możliwościami walidacji dla konstrukcji zapytania. – benjist

+0

Możesz także przekazywać selektory i argumenty. –

+0

ha, może to wszystko. Mógłbym, zamiast budować drzewo bezpośrednio, zebrać wszystkie (kopie) argumentów i selektorów. i zastosuj je we właściwej kolejności, gdy żądany jest łańcuch zapytania (w tym sprawdzanie składni, ale w późniejszym czasie). – benjist

Powiązane problemy