Dzisiejszy odcinek poświęcę obiektom, które przez ostatnie odcinki były skutecznie omijane z różnych względów. Jak mówi przysłowie "Bez OBJECTów żyć sie nie da".
Obiekty w E są równoważne strukturom w C, asemblerze i w pascalowych
recordach. Obiekty wyglądają jak ARRAY (tabele) z tą różnicą, że każdy
element ma przypisaną nazwę (która może się powtarzać w innych obiektach), a
nie numer oraz każdy z tych elementów może być innego typu (np. LONG, CHAR,
etc.). Do znalezienia określonego element w OBJECT używa się nazwy danego
elementu.
OBJECT <nazwa_obiektu>
<nazwa_elementu> [ : <typ>]
...
ENDOBJECT
Przykładowy OBJECT może wyglądać tak:
OBJECT rec tag, check tabele[8]:ARRAY data:LONG ENDOBJECT
Do znalezienia wybranego elementu w obiekcie "obj" używamy "obj.nazwa", gdzie "nazwa" jest jednym z elementów, czyli gdy chcemy odczytać "data" z OBJECT "rec" należy napisać "rec.data". Inne dane odczytujemy w podobny sposób (rec.tag, rec.check). Elementy w obiekcie deklarujemy w kolejnych linijkach lub po przecinku (typy prawie dowolne), czyli jak w przykładzie element "tag" i "check" zostały zadeklarowane domyślnie jako elementy LONG, element "table" został zadeklarowany jako tabela LONGów (DEF table[8]:ARRAY OF LONG), element "data" został również zadeklarowany jako typu LONG. Możemy również do obiektów dodawać zmienne typu CHAR, INT co przy zwykłym deklarowaniu (DEF) jest niemożliwe, np.
OBJECT dane imie[56]:ARRAY OF CHAR nazwisko[256]:ARRAY OF CHAR wiek:CHAR urodzony:LONG ENDOBJECT
Należy pamiętać, że OBJECTy deklarujemy zawsze na początku programu lub w osobnych modułach (.m). Należy również pamiętać, że nie możemy w OBJECTach używać elementów typu STRING. Po stworzeniu OBJECTu należy go przypisać do zmiennej:
PROC main() DEF dane:dane, rec:PTR TO rec ENDPROC
OBJECT możemy przypisać na dwa różne sposoby, pierwszy polega na tym, że dany OBJECT przypisujemy do zmiennej jako "opis", tzn. pod zmienną są już/będą "ukryte dane" ale nie jest podane jak te dane są ułożone.
DEF screen:PTR TO screen
Drugi sposób polega na przypisaniu do zmiennej i zarezerwowaniu wystarczającej pamięci na dany OBJECT
DEF screen:screen
Wielkość każdego OBJECTu możemy sprawdzić używając do tego polecenia:
SIZEOF <nazwa_obiektu>
Dzięki temu unikniemy sytuacji błędnego zinterpretowania wielkości obiektu.
W pierwszym przypadku przypisania (PTR TO) jeśli chcemy możemy sami zarezerwować pamięć wykorzystując do tego np. polecenia:
<zmienna> := New(SIZEOF <obiekt>), NEW <zmienna> <zmienna> := AllocMem(SIZEOF <obiekt>,MEMF_FAST+MEMF_CLEAR)
gdzie <zmienna> jest "opisana" w <obiekt>:
DEF <zmienna>:PTR TO <obiekt>
Pamiętajmy iż należy zawsze wiedzieć czy <zmienna> ma zarezerwowaną
pamięć czy nie, gdyż jeśli nie ma, a my odwołamy się/zapiszemy do
<zmienna> może się to zakończyć różnymi ciekawymi efektami od złego
działania programu do ulubionego przez programistów GURU.
xx:PTR TO zz wykorzystuje się przeważnie jeśli korzysta się z bibliotek, ponieważ funkcje bibliotek przeważnie zwracają obiekty, np. wywołanie funkcji LockDosList() spowoduje zwrócenie obiektu doslist ("emodules:dos/dosextens.m"). Oczywiście w tych wypadkach przeważnie nie musimy (chyba, że jest to wyrażnie napisane w dokumentacji danej biblioteki, sterownika, etc.) zwalniać tej pamięci. Do zwolnienia utworzonej tak listy użyjemy polecenia UnLockDosList(). Natomiast xx:zz wykorzystamy jeśli my musimy podać obiekt jakiejś procedurze zewnętrznej (np. funkcji w bibliotece).
Ja z przyzwyczajenia wykorzystuję przeważnie pierwszy sposób samemu dbając o rezerwację wymaganej ilości pamięci, daje mi to możliwość pełnej kontroli kiedy dany obiekt mi jest potrzebny, nie rezerwując pamięci na "pusty zapas".
Tak więc po tym krótkim odcinku powinniście znać podstawy budowania i używania obiektów, więcej informacji znajdziecie jak zwykle w dokumentacji (beginner.guide).
Dozwolone typy w obiektach: |
CHAR/INT/LONG/<obiekt> PTR TO CHAR/INT/LONG/<obiekt> ARRAY OF CHAR/INT/LONG/<obiekt> |
Dziś poznaliśmy: |
OBJECT xx - początek opisu obiektu xx ENDOBJECT - koniec opisu obiektu xx:zz - przypisz obiekt zz do zmiennej xx i zarezerwuj pamięć na ten obiekt xx:PTR TO zz - przypisz obiekt zz do zmiennej xx SIZEOF - pobierz rozmiar (np. obiektu lub typu) |