310 likes | 454 Views
Obiektowe języki zapytań. Wykładowca : Kazimierz Subieta Polsko-Japońska Wyższa Szkoła Technik Komputerowych, Warszawa subieta@pjwstk.edu.pl Instytut Podstaw Informatyki PAN, Warszawa subieta@ipipan.waw.pl. Wykład 10:
E N D
Obiektowe języki zapytań Wykładowca: Kazimierz Subieta Polsko-Japońska Wyższa Szkoła Technik Komputerowych, Warszawa subieta@pjwstk.edu.pl Instytut Podstaw Informatyki PAN, Warszawa subieta@ipipan.waw.pl Wykład 10: Rozszerzenie SBQL dla modeli M1, M2 i M3 (klas i dziedziczenia, dynamicznych ról, list eksportowych
Klasy i dziedziczenie • Dotychczasowe definicje operatorów języka SBQL nie uwzględniają pojęć klasy i dziedziczenia. Pokażemy w jaki sposób można je łatwo rozszerzyć na powyższe własności. • Model składu M1 wprowadza pojęcie klasy jako specjalnej struktury danych przechowywanej w ramach składu obiektów. Klasy przechowują inwarianty obiektów. • Istotnym inwariantem przechowywanym w ramach klasy może być nazwa obiektów tej klasy. • Klasy i obiekty są połączone związkami dziedziczenia. • Model M1 powoduje większą złożoność wprowadzanych przez nas definicji. Z tego punktu widzenia model M2 jest bardziej korzystny, ale też mniej popularny niż M1. • M1 jest stosowany w językach z wczesnym (statycznym) wiązaniem. • W naszym podejściu model M1 został przystosowany do koncepcji, w której wiązanie jest późne (dynamiczne).
Rozszerzenie SBQL w modelu M1 • W modelu M1 należy zmodyfikować regułę wiązania nazw. Chodzi o zachowanie zasady zamienialności (substitutability). • Przykładowo, obiekt Prac jest jednocześnie obiektem Osoba. Informacja o tej zależności jest przechowywana w modelu M1 w dwóch miejscach: (1) klasy, które przechowują nazwy należących do nich obiektów; (2) relacje KK i OK. • W terminach operacji na ENVS zmieniona reguła wiązania oznacza, że o ile w pewnej sekcji stosu znajduje się binder o nazwie Prac, zaś wiązana jest nazwa Osoba, to binder ten uczestniczy w procesie wiązania tak samo, jakby był to binder o nazwie Osoba. • M1 wprowadza nową zasadę otwierania i usuwania sekcji na ENVS. Jeżeli operator niealgebraiczny przetwarza obiekt posiadający identyfikator i, to na wierzchołek stosu środowisk wkładane są nie tylko bindery nested(i), ale poniżej wierzchołka stosu są ulokowane sekcje z binderami do własności klas tego obiektu w odpowiedniej kolejności,
Graficzna reprezentacja przykładu modelu M1 Osoba Nazwisko RokUr Wiek i40 KlasaOsoba i41 Wiek (...kod...) ................ i1 Osoba i2 Nazwisko ”Wilski” PracujeW i3 RokUr 1950 Prac Zar ZmieńZar ZarNetto i50 KlasaPrac i51 ZmieńZar (...kod...) i52 ZarNetto (...kod...) ................ i4 Prac i9 Prac i5 Nazwisko ”Nowak” i10 Nazwisko ”Kowalski” i6 RokUr 1944 i11 RokUr 1940 i7 Zar 2500 i12 Zar 2000 i8 PracujeW i13 PracujeW i127 i128
Sytuacja na ENVS dla modelu M1 Obiekt Obiekt Obiekt • Zakładamy, że operator nie-algebraiczny przetwarza obiekt O z identyfikatorem iO. Kolejność przeszukiwania stosu Bindery do własności przechowywanych wewnątrz obiektu O, czyli nested(iO) Bindery do własności przechowywanych wewnątrz K1 Bindery do własności przechowywanych wewnątrz K2 Bindery do własności przechowywanych wewnątrz K3 ............................ ........................... Bindery z identyfikatorami startowymi składu obiektów Sekcje wkładane na stos środowiskowy przy przetwarzaniu obiektu O przez operator niealgebraiczny Klasa K3 Klasa K2 Klasa K1
Zmiany w modelu M1 • Podana koncepcja automatycznie uwzględnia własność przesłaniania (overriding). Jeżeli np. klasa K1 zawiera pewną metodę m, która przesłania metodę m zawartą w klasie K2, to zgodnie z przedstawioną kolejnością przeszukiwania stosu przy wiązaniu nazwy m związana zostanie metoda m z klasy K1; metoda m z klasy K2 będzie niewidoczna. • Poprzedni slajd przedstawia stan stosu od strony koncepcji semantyki języka zapytań. Przy przetwarzaniu obiektu O na stos są wkładane cztery sekcje, a po przetworzeniu obiektu - zdejmowane. Ogólnie wkładanych jest n+1 sekcji, gdzie n jest liczbą poziomów w hierarchii klas • Wizja ta może być bezpośrednio zaimplementowana, ale jest ona dość rozrzutna jeżeli chodzi o zużycie zasobów, gdyż może przy okazji przetwarzania każdego obiektu wkładać na stos i zdejmować wiele sekcji. Możliwe są proste optymalizacje.
Przetwarzanie obiektu Prac w M1 Nazwisko(i5) RokUr (i6) Zar (i7) PracujeW (i8) ZmieńZar(i51) ZarNetto(i52) ... Wiek(i51) ... ......... Prac(i4) Prac(i9), ... Osoba(i1) Osoba(i4) Osoba(i9), ... Operator niealgebraiczny, np. where w zapytaniu PracwhereWiek > avg(Prac.Wiek) przetwarza obiekt Nowaka (z identyfikatorem i4 ) dla bazy danych przedstawionej poprzednio. Kolejność przeszukiwania stosu Sekcja zawierająca nested(i4) - własności aktualnie przetwarzanego obiektu i4 Bindery do własności klasy KlasaPrac (połączonej z i4 związkiem OK). Bindery do własności klasy KlasaOsoba (połączonej z KlasaPrac związkiem KK). ... inne sekcje ... Bindery do obiektów bazy danych, zdublowane dla różnych nazw.
Zdublowane bindery w M1 • Sekcja binderów do obiektów bazy danych zawiera bindery do obiektów i4 oraz i9 opatrzone zarówno nazwą Prac, jak i nazwą Osoba. • Jest to jeden z wariantów uwzględnienia zasady zamienialności. • Dodatkowe bindery Osoba pojawiają się na podstawie nazw obiektów będących inwariantami klas oraz związku KK. • Zakładamy tu, że jeżeli wiązana była nazwa Osoba, to kontrola typologiczna ograniczy możliwość użycia własności obiektu Prac nie będących atrybutami obiektów Osoba. • Dla języków pozbawionych mocnej kontroli typów ta metoda może prowadzić do anomalii; np. wiążąc nazwę Osoba mamy dostęp do takich własności jak Zar i ZarNetto. Jest to sprzeczne z zasadami obiektowości. • W klasycznych modelach obiektowych problem nie występuje, gdyż: • typy lub klasy nie przesądzają nazw obiektów, • zasada zamienialności jest konsekwencją hierarchii dziedziczenia klas lub typów.
Przetwarzanie metod • Dotychczas przyjmowaliśmy, że wiązanie polega wyłącznie na tym, że nazwę występującą w zapytaniu zamienia się np. na referencję obiektu na podstawie bindera wyszukanego na stosie ENVS. Dla metod ta zasada jest rozszerzona. • Jeżeli wiązana nazwa jest nazwą metody, to: • Następuje wiązanie jej nazwy jak zwykle na stosie ENVS; • Po związaniu, metoda jest wywoływana; • Wywołanie metody powoduje utworzenie nowej sekcji na stosie ENVS - zapisu aktywacji, zawierającego bindery do lokalnego środowiska metody, tj. jej parametrów i lokalnych obiektów, następnie wejście sterowania w kod. • Zapis aktywacji zawiera także ślad powrotu z metody. • Aktualne parametry metody są pobierane ze stosu rezultatów QRES i następnie wstawiane do lokalnego środowiska. • Niekiedy może nam zależeć na pobraniu identyfikatora metody, a nie na jej wywołaniu, np. celem przekazania metody jako parametru. W tym celu potrzebna jest specjalna składnia, np. refWiek.
Co się dzieje, gdy wołana jest metoda? q ... met(q1, q2)... Użycie metody w zapytaniu: Implementacja metody w ramach klasy K methodmet( p1: T1, p2: T2 ): T (*sygnatura*) begin x1: T11, x2: T12; (* lokalne obiekty *) .... endmet; gdzie jest operatorem niealgebraicznym Niech eval(q) zwróci bag{r1, r2, ....}, gdzie r1, r2, ...., są referencjami do obiektów będących członkami klasy K. Następny slajd przedstawia sytuacje powstające na stosach.
Stany stosów podczas przetwarzania metody Kroki przetwarzania dla r1: Przetwarzanie ciała met Obliczenie parametrów, wiązanie i wywołanie metody met Sekcja lokalna met p1 (Rezultat q1) p2(Rezultat q2) x1(..) x2(..) Bindery do prywatnych własności K nested(r1) Bindery do publicznych własności K ....... Sekcje globalne Operator Po zakończeniu działania met ENVS nested(r1) Bindery do publicznych własności K ....... Sekcje globalne nested(r1) Bindery do publicznych własności K ...... Sekcje globalne ....... Sekcje globalne czas Usunięcie rezultatów q1, q2 QRES Obliczenie q Rezultat q2 Rezultat q1 Rezultat q Poprzedni stan QRES Rezultat met Rezultat q Poprzedni stan QRES Rezultat q Poprzedni stan QRES Rezultat q Poprzedni stan QRES
Podsumowanie zmian semantycznych w M1 • Zmiany w globalnych sekcjach binderów (m.in. do bazy danych): dowolny binder n(i) wynikający ze zbioru R identyfikatorów startowych jest uzupełniany poprzez bindery n1(i), n2(i), ... , gdzie n1, n2,... są nazwami ustalonymi jako inwarianty klas nadrzędnych w stosunku do klasy do której należy obiekt i. • Jeżeli operator niealgebraiczny przetwarza obiekt z identyfikatorem i należący do klasy K1, która ma kolejne superklasy K2, K3, ..., wówczas na wierzchołek stosu środowiskowego wkłada się po kolei, poczynając od wierzchołka: nested(i), bindery do własności K1, bindery do własności K2, bindery do własności K3, itd. • Dla metod wiązanie nazw jest skojarzone z wywołaniem. Wywołanie oznacza obliczenie parametrów metody, założenie nowej sekcji (zapisu aktywacji) na czubku ENVS, i następnie, przekazanie sterowania do kodu metody. Nowa sekcja zawiera bindery parametrów, bindery lokalnych obiektów, oraz ślad powrotu.
Wielodziedziczenie w M1 i fałszywe przesłanianie Bindery do własności obiektu O Bindery do własności K1 Bindery do własności K2 Bindery do własności K3: m (...) Bindery do własności K4: m (...) Bindery do własności K5 ..... Bindery danych globalnych Klasa K4 metoda m Klasa K3 metoda m Obiekt Obiekt Obiekt • Metoda m z klasy K4 jest przesłonięta przez metodę m z klasy K3, przez co metoda m z klasy K4 nie ma szansy na to, aby była użyta. • Jest to złamanie zasady zamienialności (substitutability) Klasa K5 Kierunek przeszukiwania stosu Klasa K2 Klasa K1 Stos środowisk przy przetwarzaniu obiektu O Skład obiektów
Wielokrotne dziedziczenie w M1 • Jeżeli pewna klasa dziedziczy z większej liczby klas, to możliwe są dwa przypadki: • Nie występuje konflikt nazw pomiędzy własnościami dziedziczonymi z poszczególnych klas. W tym przypadku kolejność klas na stosie powinna uwzględniać hierarchię klas, ale kolejność klas na tym samym poziomie hierarchii nie ma znaczenia. • Jeżeli występuje konflikt pomiędzy własnościami dziedziczonymi z poszczególnych klas, to nie istnieje dobry porządek ustawienia klas na stosie. Każdy porządek łamie zasadę zamienialności. Jest to inherentna wada modelu M1, która jest wyeliminowana w modelu M2. • Nie ma sposobu uniknięcia anomalii wielodziedziczenia w modelu M1. • Jeżeli zabronimy użycia identycznych nazw metod w nadklasach, to łamiemy zasadę "klasa otwarta dla specjalizacji, zamknięta dla zmian". • Jeżeli dopuścimy zmianę nazwy metody w podklasie, to łamiemy zarówno zasadę zamienialności, jak i zasadę koncepcyjnej kontynuacji.
Skąd problemy wielodziedziczenia w M1? • Wynikają one z faktu zmieszania w jednym środowisku własności różnych klas, często niekompatybilnych. • Jest to przyczyna tego, że w niektórych językach i systemach zrezygnowano z wielokrotnego dziedziczenia. • Nie usuwa to problemu, ponieważ w ten sposób zwiększa się dystans pomiędzy modelowaniem pojęciowym a modelem implementacyjnym. • Brak wielodziedziczenia łamie zasadę „otwarte-zamknięte” (open-close principle), podstawowej dla ponownego użycia (reuse). • Model a la M1 jest stosowany w większości języków i systemów obiektowych (z różnymi nazwami, mutacjami i własnościami). Niezależnie od tego, czy zezwala on na wielodziedziczenie (C++, OMG CORBA, standard ODMG, standardy SQL3 i SQL1999), czy też nie (Smalltalk, Java), zawsze pojawią się w nim pewne wady bądź w zakresie modelowania pojęciowego, bądź też w postaci anomalii technicznych tworzących rafy dla programistów. • Sposobem usunięcia tych wad jest przyjęcie modelu M2 (i modeli pochodnych), zakładających koncepcję dynamicznych ról obiektów.
Przykłady zapytań w modelu M1 - schemat Osoba[0..*] Nazwisko RokUr Wiek() PracujeW Zatrudnia[1..*] Prac[0..*] NrP Stan[1..*] Zar[0..1] ZmieńZar(nowyZar) ZarNetto( ) Dział [0..*] NrD Nazwa Lokacja[1..*] BudżetRoczny() Kieruje[0..1] Szef
Przykłady zapytań w modelu M1 Nazwa działu i średni wiek jego pracowników: Dział . ( Nazwa, avg(Zatrudnia.Prac.Wiek()) asŚrednia) Dziedziczenie metody Wiek przez klasę Prac. Podaj nazwiska, zarobek netto i nazwisko szefa dla programistów pracujących w Radomiu. (DziałwhereLokacjaasx (x = "Radom" )) join (Zatrudnia.Pracwhere "programista" Zawód ). (Nazwisko, ZarNetto() asnetto, (Szef.Prac.Nazwisko) asboss) Dziedziczenie atrybutu Nazwisko przez klasę Prac. Dla każdego pracownika podaj nazwisko oraz procent budżetu przeznaczony na jego uposażenie. Prac. (Nazwisko as NazwiskoPracownika, (Zar * 12 * 100 / (PracujeW.Dział.BudżetRoczny())) asProcentBudżetu)
Rozszerzenie SBQL w modelu M2 • Jak dotąd, tylko podejście stosowe jest przystosowane do koncepcji obiektowości zakładającej dynamiczne role obiektów, określanej przez nas jako model M2. • Pozostałe podejścia, takie jak obiektowe algebry, nie tylko nie rozważają takiej koncepcji, ale są niespójne w stosunku do prostszego modelu M1. • Zmiana w stosunku do modeli M0 i M1 polega na sposobie zapełniania bazowych sekcji stosu. W tym przypadku sekcja bazowa ENVS musi zawierać bindery do wszystkich ról obiektów, gdyż identyfikatory startowe (zbiór R) obejmują wszystkie aktualne role wszystkich obiektów. • W modelu M2 obiekt występuje wyłącznie jako konglomerat ról, z jedną wyróżnioną rolą główną.
Graficzna reprezentacja przykładu modelu M2 i40 KlasaOsoba i41 Wiek (...kod...) ............. i1 Osoba i60 KlasaStudent i2 Nazwisko ”Wilski” i61 ŚredniaOcen (...kod...) i3 RokUr 1950 ................ i50 KlasaPrac i51 ZmieńZar (...kod...) i52 ZarNetto (...kod...) ................ i4 Osoba i5 Nazwisko ”Nowak” i7 Osoba i6 RokUr 1944 i8 Nazwisko ”Kowalski” i9 RokUr 1940 i19 Student i13 Prac i16 Prac i20 NrIndeksu 76943 i14 Zar 2500 i17 Zar 2000 i21 Wydział ”fizyka” i15 PracujeW i18 PracujeW i128 i127
Dolne sekcje ENVS w modelu M2 .................... Bindery do obiektów/zmiennych nietrwałych aktualnej sesji użytkownika Osoba( i1 ) Osoba( i4 ) Osoba( i8 ) Prac( i13 ) Prac( i16) Student( i19) ... Bindery do globalnych funkcji bibliotecznych Bindery do zmiennych i funkcji środowiska komputerowego Sekcja bazy danych Sekcje danych globalnych
Przykład stanu stosu ENVS dla M2 • Zapytanie ma postać Pracwhere ... n ... • Przetwarzana jest rola z identyfikatorem i16 , wiązana jest nazwa n Kolejność przeszukiwania stosu Zar( i17 ) PracujeW( i18 ) ZmieńZar( i51 ) ZarNetto( i52 ) ... Nazwisko( i8 ) RokUr( i9 ) Wiek( i41 ) ... ......... Osoba( i1 ) Osoba( i4 ) Osoba( i8 ) Prac( i13 ) Prac( i16) Student( i19) ... ......... Bindery do własności aktualnie przetwarzanej roli Prac Bindery do własności klasy KlasaPrac Bindery do własności roli Osoba będącej super-rolą aktualnie przetwarzanej roli Prac Bindery do własności klasy KlasaOsoba Sekcja bazy danych
Uogólnienie: skład z rolami w M2 iK3R1 K3R1 iK3R2 K3R2 iK3R3 C3R3 iK2R1 K2R1 iK2R2 K2R2 iK2R3 K2R3 iK1R3 K1R3 iK1R1 K1R1 iK1R2 K1R2 • Klasy KjRi (j = 1,2,...) nie muszą być unikalne; mogą tworzyć graf dziedziczenia. Klasy iR3 R3 Obiekty i role iR2 R2 Obiekt z rolami iR1 R1
Organizacja i kolejność przeszukiwania ENVS • Operator nie-algebraiczny przetwarza rolę R1 nested(iR1) nested(iK1R1) nested(iK2R1) ... nested(iR2) nested(iK1R2) nested(iK2R2) ... nested(iR3) nested(iK1R3) ... ... Kolejność przeszukiwania stosu sekcje roli R1 sekcje roli R2 sekcje roli R3
Uwagi do poprzedniego rysunku • Może się zdarzyć, że pewne sekcje klas wkładanych na stos będą się powtarzać. • Poza koncepcyjną redundancją (którą można łatwo wyeliminować w implementacji) w niczym to nie przeszkadza, ponieważ istotna będzie tylko ta sekcja, która jest najbliższa wierzchołka stosu. • Duplikaty sekcji znajdujące się poniżej w stosie nie będą uczestniczyć w wiązaniu nazw. • Po ewaluacji zapytania q2 wszystkie te sekcje będą zdjęte ze stosu. • Reguły wiązania nazw są takie same jak w przypadku modelu M0. • Nie występują tu anomalie przy wiązaniu nazw, które były omawiane przy okazji modelu M1.
Operatory rzutowania w modelu M2 • Model M2 implikuje operator algebraicznego znany z innych języków pod nazwą „rzutowanie” (casting). • Chodzi o możliwość przełączenia się z danej roli obiektu do innej roli tego samego obiektu. Syntaktycznie, operator ten będzie zapisywany w postaci: (nazwa) zapytanie gdzie nazwa jest nazwą roli, zapytanie zwraca wielozbiór identyfikatorów ról. • Operator ten dla danego identyfikatora roli zwróconego przez zapytanie wyszukuje w ramach tego samego obiektu role nazwa. Operator zwraca identyfikatory ról. Końcowy wynik jest sumą mnogościową wyników dla wszystkich identyfikatorów zwróconych przez zapytanie. • Przykład. Podaj pracowników, którzy są jednocześnie studentami. (Prac) Student Ewaluacja zapytania Student zwróci identyfikatory wszystkich ról Student. Operator rzutowania (Prac) zmieni niektóre z nich na identyfikatory ról Prac (jeżeli obiekt ma jednocześnie role Student i Prac), zaś inne na wartość pustą.
Przykład operatora rzutowania • Załóżmy, że role Student mają atrybut Stypendium. Dla każdej osoby należy zwrócić Nazwisko oraz dochody, które wynoszą 0, jeżeli dana osoba nie jest ani pracownikiem ani studentem, Zar jeżeli osoba jest pracownikiem, Stypendium jeżeli osoba jest studentem, lub Zar+Stypendium, jeżeli osoba jest jednocześnie pracownikiem i studentem. (Osobaasp) . (p.Nazwisko, sum( bag( 0, ((Student)p).Stypendium, ((Prac)p).Zar ) ) • sum jest funkcją agregowaną znaną z SQL. Pomocnicza nazwa p „obiega” wszystkie role Osoba. Po pierwszej kropce następuje wyliczenie wyniku dla pojedynczej wartości p. Na wynik ten składa się Nazwisko danej osoby oraz suma dochodów. Dla wyliczenie tej sumy tworzy się wielozbiór składając się z jednego, dwóch lub trzech elementów. Jeżeli p posiada rolę Student, to p jest rzutowane na tę rolę, z tej roli pobiera się Stypendium; podobnie dla roli Prac i atrybutu Zar. • Podane zapytanie automatycznie uwzględni fakt, że dana osoba jest kilkakrotnie pracownikiem i/lub kilkakrotnie studentem.
Rozszerzenie SBQL w modelu M3 • Model M3 rozszerza M1 i M2 o listę eksportową, która dzieli własności klasy oraz własności obiektów tej klasy na publiczne i prywatne. • Własności prywatne zarówno klasy K, jak i obiektów klasy K, są dostępne wyłącznie z wnętrza ciała metod (publicznych i prywatnych) klasy K. • Można to prosto zrealizować poprzez odpowiednie ustawienie sekcji stosu oraz poprawkę do funkcji nested. Niech iK będzie identyfikatorem obiektu klasy K posiadającej listę eksportową exportK • nested_private( iK ) = {n(x) : nnested( iK ) and nexportK} • nested_public( iK ) = {n(x) : nnested( iK ) and nexportK} • Dla pozostałych argumentów funkcje te nie ulegają zmianie. • Funkcje te w sposób naturalny (czyli podobnie jak poprzednio) rozszerzamy na dowolne struktury: nested_private( struct{ x1, x2, ...}) = nested_private( x1 ) nested_private( x2 ) ... nested_public( struct{ x1, x2, ...}) = nested_public( x1 ) nested_public( x2 ) ...
Przetwarzanie obiektów w M3 nested_public(ri) nested_public(iK1) nested_public(iK2) nested_public(iK3) Poprzedni stan ENVS • Zapytanie q1 q2, gdzie jest operatorem niealgebraicznym. • Niech eval(q) zwróci bag{r1, r2, ....}, gdzie r1, r2, .... są referencjami do obiektów będących członkami klasy K1, która jest podklasą K2, która jest podklasą K3. • Niech wiązana będzie pewna nazwa m występująca w q2 ; m nie jest nazwą metody. • Kroki przetwarzania dla ri: Koniec przetwarzania ri przez q2 Operator Sekcje wkładane przy przetwarzaniu ri Poprzedni stan ENVS Poprzedni stan ENVS
Przetwarzanie metod w M3 Lokalne środowisko metody m nested_private(iK2) nested_ private(ri) nested_public(ri) nested_public(iK1) nested_public(iK2) nested_public(iK3) Poprzedni stan ENVS nested_public(ri) nested_public(iK1) nested_public(iK2) nested_public(iK3) Poprzedni stan ENVS nested_public(ri) nested_public(iK1) nested_public(iK2) nested_public(iK3) Poprzedni stan ENVS • Założenia jak poprzednio. • Niech wiązana będzie pewna nazwa n występująca w q2 ; m jest nazwą metody, która znajduje się w klasie K2. • Kroki przetwarzania dla ri: Prywatne własności klasy K2 Wywołanie metody m Prywatne własności obiektu z OID = ri Środowisko indukowane przez wywołanie m Środowisko indukowane przez Poprzedni stan ENVS Poprzedni stan ENVS
Reguły zakresu dla M3 • Załóżmy, że dla rozpatrywanego zapytania q1 q2 zachodzi: • aktualnie wykonywana jest metoda m1 występująca w q2 i przetwarzająca ri • zapytanie występuje wewnątrz ciała metody m2 • m2 została wywołana z metody m3 Kolejność wiązania nazw występujących w ciele m1 Środowisko indukowane przez wywołanie m1dla ri Środowisko indukowane przez q2 , w którym zanurzone jest wołanie metody m1 Środowisko indukowane przez dla ri Środowisko indukowane przez wywołanie m2 Środowisko indukowane przez wywołanie m3 ... Sekcje bazowe ENVS Lexical scoping: programista piszący m1 nie znał tych środowisk. Wobec tego nazwy występujące w m1 nie mogą być w nich wiązane.
Przykłady poprawnych i błędnych zapytań w M3 Osoba + Nazwisko - RokUr + Wiek Prac - Zar + ZmieńZar + ZarNetto OsobawhereNazwisko = "Nowak" Poprawne Błędne (OsobawhereNazwisko = "Nowak").RokUr Poprawne (PracwhereNazwisko = "Nowak").Wiek procedureWiek() { returnBieżącyRok - RokUr } Poprawne (PracwhereNazwisko = "Nowak").Zar Błędne procedureZmieńZar( nowy ) { Zar := nowy } Poprawne + PracujeW procedureZarNetto( ) { ifRokUr > 1955 then return 0.9 * Zarelse return 0.8 * Zar } + Zatrudnia Błędne Dział + Nazwa + Budżet PracwhereDział (Budżet > 100 * ZarNetto) .... procedureZarNetto( ) { ifNazwa = "Marketing" then return 0.9 * Zarelse return 0.8 * Zar } Błędne