Magik (język programowania)
Magik – obiektowy język programowania, który obsługuje wielodziedziczenie, polimorfizm i typowanie dynamiczne. Jest on dostarczony przez GE Energy jako część platformy technologicznej Smallworld i został zaprojektowany od początku do realizacji złożonych aplikacji dla przedsiębiorstw użyteczności publicznej takich jak dystrybucja energii i telekomunikacji. Przeznaczony jest do tworzenia aplikacji GIS, stosowany w Smallworld GIS.
Magik (Inspirational Magik) został pierwotnie wprowadzony w 1990 r. i został poprawiony i zaktualizowany na przestrzeni lat. Jego obecną wersją jest 4.0 lub Magik SF (Small Footprint).
Podobieństwo do języka Smalltalk
[edytuj | edytuj kod]Magik jest podobny do Smalltalka pod względem cech języka i jego architektury: Programy w Magiku są kompilowane do kodu bajtowego interpretowanego przez maszynę wirtualną Magika. Maszyna wirtualna Magika jest dostępna na wielu platformach, w tym Microsoft Windows i różnych odmianach Uniksa i Linuksa.
Magik opiera się na konsoli i jego kod może być modyfikowany w locie, nawet gdy aplikacja jest uruchomiona. Konsola może być również wykorzystana do wykonania kodu Magika i aby zobaczyć wyniki.
Skompilowany kod jest przechowywany w jednym pliku o nazwie plik obrazu. Każdy plik obrazu trzyma kod bajtowy i stan sesji (np. wartości zmiennych) jaki był gdy obraz został ostatnio zapisany.
Funkcje języka
[edytuj | edytuj kod]- Komentarze
Magik używa znaku #
do zaznaczania części kodu jako komentarze:
# To jest komentarz.
- Przypisania
Magik używa operatora <<
aby przypisać:
a << 1.234 b << b + a c << "foo" + "bar" # Łączenie łańcuchów
Dla jasności, ten zapis jest odczytywany jako "a staje się równe 1,234" czy "b staje się równe b plus a". Ta terminologia oddziela przypisanie od porównania.
Magik obsługuje również skompresowaną odmianą tego operatora, który działa w sposób podobny do tych z C:
b +<< a # Odpowiednik b << b + a
- Symbole
Zarówno jak konwencjonalne typy danych takie jak liczby całkowite, zmiennoprzecinkowe i łańcuchy, Magik również implementuje symbole. Symbole są specjalnymi leksemami typu danych które są używane często w Magiku do unikalnej identyfikacji obiektów. Reprezentowane są przez ciąg znaków poprzedzony dwukropkiem. Na przykład:
a << :hello # kiedykolwiek jest napotkane :hello to jest ta sama instancja
- Dynamiczne typowanie
Zmienne Magika nie mają ustalonego typu i mogą odwoływać się do różnych obiektów w czasie wykonania.
Wszystko w Magiku jest obiektem (nie ma rozróżnienia pomiędzy obiektami a prostymi typami jak liczby całkowite):
a << 1.2 # liczba rzeczywista jest przypisana do zmiennej 'a' a << "1.2" # później string jest przypisany do zmiennej 'a'
- Obiekty
Obiekty są implementowane w Magiku przy użyciu egzemplarzy. Egzemplarze są podobne do klas w innych językach programowania takich jak Java, ale mają istotne różnice. Magik obsługuje wielokrotne dziedziczenie i mixiny (które implementują funkcjonalność bez danych). Nowe instancje są tworzone przez klonowanie istniejącej instancji (która zazwyczaj jest egzemplarzem ale nie musi być).
Nowe egzemplarze są tworzone za pomocą instrukcji def_slotted_exemplar()
, na przykład:
def_slotted_exemplar(:my_object, { {:slot_a, 34}, {:slot_b, "hello"} }, {:parent_object_a, :parent_object_b})
Ten fragment kodu definiuje nowy egzemplarz zwany my_object
który ma dwa sloty (lub pola) zwane slot_a
(zainicjowany na 34) i slot_b
(zainicjowany na "hello") i dziedziczy z dwóch istniejących egzemplarzy zwanych parent_object_a
i parent_object_b
.
- Porównanie
Magik implementuje wszystkie zwykłe operatory logiczne (=
, <
, <=
, >
, >=
, ~=/<>
) do porównań, jak również parę niecodziennych. Operatory _is
oraz _isnt
są używane do porównywania określonych instancji obiektów zamiast wartości.
Na przykład:
a << "hello" b << "hello"
a = b zwraca True (_true) ponieważ wartości a i b są równe a _is b zwraca False (_false) ponieważ a nie jest tą samą instancją co b
a << "hello" b << a = b zwraca True (_true) ponieważ wartości a i b są równe a _is b zwraca True (_true) ponieważ do b przypisaliśmy instancję obiektu a zamiast wartości a.
- Metody
Metody są definiowane w egzemplarzach za pomocą instrukcji _method
i _endmethod
:
_method my_object.my_method(a, b) _return a + b _endmethod
Jest to konwencja dostarczenia dwóch metod new()
(do utworzenia nowej instancji) and init()
(do zainicjowania instancji).
# Metoda new _method person.new(name, age) _return _clone.init(name, age) _endmethod
# Metoda inicjalizacji. _private _method person.init(name, age) # Wywołanie implementacji rodzica. _super.init(name, age) # Inicjalizacja slotów. .name << name .age << age _return _self _endmethod
Wywołanie _clone
tworzy fizyczną kopię obiektu person
. Wywołanie _super
pozwala obiektom na wywołanie implementacji metody egzemplarza rodzica. Obiekty mogą odwoływać się do siebie używając _self
. Sloty obiektu są dostępne i przypisywanie za pomocą notacji z kropką.
Metody które nie są częścią publicznego interfejsu obiektu mogą być oznaczone jako prywatne przy użyciu _private
. Prywatne metody mogą być wołane wyłącznie przez _self
, _super
i _clone
.
Opcjonalne argumenty mogą być deklarowane przy użyciu _optional
. Opcjonalne argumenty które nie są przekazywane są przypisywane przez Magika do specjalnego obiektu _unset
(odpowiednik null). Do deklarowania listy opcjonalnych argumentów może być użyte _gather
.
_method my_object.my_method(_gather values) _endmethod
- Iteracja
W Magiku na iteracje pozwalają _for
, _over
, _loop
i _endloop
.
_method my_object.my_method(_gather values) total << 0.0 _for a _over values.elements() _loop total +<< a _endloop _return total _endmethod
m << my_object.new() x << m.my_method(1.0, 2, 3.0, 4) # x = 10.0
Tutaj values.elements() jest iteratorem który pomaga iterować wartości.
W Magiku metody generatora są zwane metodami iteratora. Nowe metody iteratora mogą być definiowane za pomocą _iter
oraz _loopbody
:
_iter _method my_object.even_elements() _for a _over _self.elements() _loop _if a.even? _is _true _then _loopbody(a) _endif _endloop _endmethod
- Procedury
Magik obsługuje również funkcje zwane procedurami. Procedury są również obiektami i są deklarowane przy użyciu _proc
i _endproc
. Procedury są przypisane do zmiennych które mogą być następnie wywoływane:
my_procedure << _proc @my_procedure(a, b, c) _return a + b + c _endproc
x << my_procedure(1, 2, 3) # x = 6
- Dziwactwa językowe
Ponieważ Magik był oryginalnie rozwijany w Anglii, metody w jądrze bibliotek Smallworlda są pisane przy użyciu brytyjskiej odmiany języka angielskiego. Na przykład:
Użyj "initialise" zamiast "initialize".
- Kolekcje
Podobnie jak inne języki programowania Magik też ma kolekcje. Należą do nich:
- Simple Vector
- Rope
- Hash Table
- Property List
- Equality set
- Bags
Przykład Hello World
[edytuj | edytuj kod]Oto przykład z Hello world napisany w Magiku:
write ("Hello World!")
Linki zewnętrzne
[edytuj | edytuj kod]- Smallworld Product Suite Technology
- MDT - Magik Development Tools IDE dla deweloperów GE Smallworld GIS
- Open Source (SourceForge) biblioteki do Smallworld GIS
- Posty na temat Magika
- Technical Paper No. 5 - Przegląd Smallworld Magik