Magik — это объектно-ориентированный язык программирования, поддерживающий множественное наследование и полиморфизм , и он динамически типизирован . Он был разработан и реализован в 1989 году Артуром Ченсом из Smallworld Systems Ltd. как часть Smallworld Geographical Information System (GIS). После приобретения Smallworld в 2000 году Magik теперь предоставляется GE Energy , по-прежнему как часть ее технологической платформы Smallworld.
Magik (Inspirational Magik) был первоначально представлен в 1990 году и с годами совершенствовался и обновлялся. Текущая версия — 5.2.
В июле 2012 года разработчики Magik объявили, что они находятся в процессе портирования языка Magik на виртуальную машину Java . Успешное портирование было подтверждено корпорацией Oracle в ноябре того же года. [1]
Сам Magik имеет некоторые сходства с Smalltalk с точки зрения языковых особенностей и архитектуры: язык Magik компилируется в байт-коды, интерпретируемые виртуальной машиной Magik . Виртуальная машина Magik доступна на нескольких платформах, включая Microsoft Windows , различные разновидности Unix и Linux .
Magik — консольный, и код можно изменять на лету, даже когда приложение запущено. Консоль также можно использовать для выполнения кода Magik и просмотра результатов.
Скомпилированный код хранится в одном файле, называемом файлом изображения. Каждый файл изображения содержит скомпилированные байт-коды и состояние сеанса (например, значения переменных), когда изображение было сохранено в последний раз.
Magik использует #
токен для обозначения разделов кода как комментариев:
# Это комментарий.
Magik использует <<
оператора для выполнения заданий :
а << 1.234 б << б + а c << "foo" + "bar" # Объединяет строки
Для ясности эта запись читается как "a становится 1,234" или "b становится b плюс a". Эта терминология отделяет присваивание от сравнения .
Magik также поддерживает сжатую версию этого оператора, которая работает аналогично операторам в C :
b +<< a # Эквивалентно b << b + a
Чтобы распечатать переменную, вы можете использовать следующую команду:
а << "привет" написать(а)
Наряду с обычными типами данных, такими как целые числа, числа с плавающей точкой и строки, Magik также реализует символы. Символы — это специальный тип данных-токен, который широко используется в Magik для уникальной идентификации объектов. Они представлены двоеточием, за которым следует строка символов. Символы можно экранировать с помощью символа вертикальной черты . Например:
a << :hello # всякий раз, когда встречается :hello, это один и тот же экземпляр б << :|привет мир|
Переменные Magik не типизированы, как, скажем, в C#, и могут ссылаться на различные объекты во время выполнения. Все в Magik является объектом (нет различия между объектами и примитивными типами, такими как целые числа):
a << 1.2 # число с плавающей точкой присваивается переменной 'a' a << "1.2" # позже, строка присваивается переменной 'a'
Объекты реализуются в Magik с помощью экземпляров. Образцы имеют сходство с классами в других языках программирования, таких как Java , но с важными отличиями. Magik поддерживает множественное наследование и миксины (которые реализуют функциональность без данных). Новые экземпляры создаются путем клонирования существующего экземпляра (который обычно будет экземпляром, но не обязательно).
Новые образцы создаются с помощью оператора def_slotted_exemplar()
, например:
def_slotted_exemplar(:my_object, { {:слот_а, 34}, {:slot_b, "привет"} }, {:родительский_объект_a, :родительский_объект_b})
Этот фрагмент кода определит новый экземпляр с именем , my_object
имеющий два слота (или поля) с именами slot_a
(предварительно инициализированный значением 34) и slot_b
(предварительно инициализированный значением «hello»), который наследует от двух существующих экземпляров с именами parent_object_a
и parent_object_b
.
Magik реализует все обычные логические операторы ( =
, <
, <=
, >
, >=
, ~=/<>
) для сравнения, а также несколько необычных. Операторы _is
и _isnt
используются для сравнения конкретных экземпляров объектов или ссылок на объекты, а не значений.
Например:
а << "привет" б << "привет" a = b # возвращает True (_true), потому что значения a и b равны a _is b # возвращает False (_false), потому что a не является тем же экземпляром, что и b а << "привет" б << а a = b # возвращает True (_true), потому что значения a и b равны a _is b # возвращает True (_true), поскольку b был назначен конкретный экземпляр того же объекта, что и a, а не значение a.
Методы определяются на образцах с использованием операторов _method
и _endmethod
:
_метод мой_объект.мой_метод(a, b) _возврат а + б _endmethod
Принято предоставлять два метода new()
(для создания нового экземпляра) и init()
(для инициализации экземпляра).
# Новый метод _метод person.new(имя, возраст) _return _clone.init(имя, возраст) _endmethod # Инициализируем метод. _частный _метод person.init(имя, возраст) # Вызов родительской реализации. _super.init(имя, возраст) # Инициализируем слоты. .имя << имя .возраст << возраст _вернуть _себя _endmethod
Создает _clone
физическую копию объекта person
. _super
Оператор позволяет объектам вызывать реализацию метода родительского экземпляра. Объекты могут ссылаться на себя с помощью _self
оператора. Доступ к слотам объекта и их назначение осуществляется с помощью точечной нотации.
Методы, которые не являются частью открытого интерфейса объекта, могут быть помечены как частные с помощью _private
оператора. Частные методы могут быть вызваны только с помощью _self
, _super
и _clone
.
Необязательные аргументы могут быть объявлены с помощью _optional
оператора. Необязательные аргументы, которые не передаются, назначаются Magik специальному объекту _unset
(эквивалент null). _gather
Оператор может быть использован для объявления списка необязательных аргументов.
_метод мой_объект.мой_метод(_собрать значения) _endmethod
В Magik операторы _while
, _for
, _over
, _loop
и _endloop
допускают итерацию.
_блокировать_локальные с << 0_локальный я << 0_пока я <= 100_петляс +<< яя +<< 1_endloop>> с_endblock
Здесь _while объединено с _loop и _endloop.
_метод мой_объект.мой_метод(_собрать значения) всего << 0.0 _для _над значениями.элементы() _петля всего +<< а _endloop _вернуться в общей сложности _endmethod m << мой_объект.новый() x << m.my_method(1.0, 2, 3.0, 4) # x = 10.0
Здесь values.elements() — это итератор, который помогает перебирать значения.
В Magik методы генератора называются методами итератора. Новые методы итератора можно определить с помощью операторов _iter
и _loopbody
:
_iter _method my_object.even_elements() _для _над _self.elements() _петля _если а.чет? _истина _затем _loopbody(a) _endif _endloop _endmethod
Magik также поддерживает функции, называемые процедурами. Процедуры также являются объектами и объявляются с помощью операторов _proc
и _endproc
. Процедуры назначаются переменным, которые затем могут быть вызваны:
моя_процедура << _процедура @моя_процедура(a, b, c) _возврат а + б + в _endproc х << моя_процедура(1, 2, 3) # х = 6
Magik поддерживает // синтаксис регулярных выражений:
_if /Привет\,\s(\w)+!/.matches?("Привет, Мэджик!") _then write("Есть совпадение!")_endif
и для захвата групп в Regex:
/sw([0-9]+)-([0-9]+).*/.replace_all("sw65456-324sss", "$1") # "65456"/sw([0-9]+)-([0-9]+).*/.replace_all("sw65456-324sss", "$2") # "324"
Magik поддерживает выполнение HTTP- или HTTPS-запросов через библиотеку http, см. примеры ниже:
magikhttp << http.new()magikhttp.url("https://www.google.com").get()magikhttp.url("https://www.google.com").post({"User-agent", "Bot"}, "some data")
Поскольку Magik изначально разрабатывался в Англии, методы в основных библиотеках smallworld пишутся с использованием британского английского . Например:
Используйте «инициализировать», а не «инициализировать».
Как и в других языках программирования, в Magik тоже есть коллекции. Они включают в себя следующее:
Ниже приведен пример программы Hello world, написанной на Magik:
написать("Привет, мир!")
Благодаря этой новой возможности GE Energy удалось разместить свою среду Magik поверх виртуальной машины Java.