Из Википедии, бесплатной энциклопедии
Перейти к навигации Перейти к поиску

Eiffel - это объектно-ориентированный язык программирования, разработанный Бертраном Мейером (сторонником объектной ориентации и автором разработки объектно-ориентированного программного обеспечения ) и Eiffel Software. Мейер придумал язык в 1985 году с целью повышения надежности разработки коммерческого программного обеспечения; [5] первая версия стала доступна в 1986 году. В 2005 году Eiffel стал стандартизированным языком ISO .

Дизайн языка тесно связан с методом программирования Eiffel. Оба они основаны на наборе принципов, в том числе дизайна по контракту , разделения команды-запрос , в принципе равномерной доступы , в принцип однократный выбора , в открытом закрытом принцип , и вариант-операнде разделение .

Многие концепции, первоначально введенные Эйфелем, позже нашли свое отражение в Java , C # и других языках. [6] Новые идеи языкового дизайна, особенно в процессе стандартизации Ecma / ISO , продолжают внедряться в язык Eiffel.

Характеристики [ править ]

Ключевые характеристики языка Eiffel включают:

  • Объектно-ориентированная программная структура, в которой класс служит базовой единицей декомпозиции.
  • Дизайн по контракту тесно интегрирован с другими языковыми конструкциями.
  • Автоматическое управление памятью, обычно реализуемое сборкой мусора .
  • Наследование , включая множественное наследование , переименование , переопределение , «выбор», наследование , не соответствующее требованиям , и другие механизмы, предназначенные для обеспечения безопасности наследования.
  • Общее программирование с ограничениями и без ограничений
  • Единая система типов, обрабатывающая семантику значений и ссылок, в которой все типы, включая базовые типы, такие как INTEGER, основаны на классах.
  • Статическая типизация
  • Защита от аннулирования или статическая защита от вызовов нулевых ссылок через механизм прикрепленных типов.
  • Агенты или объекты, которые обертывают вычисления, тесно связанные с замыканиями и лямбда-исчислением .
  • Один раз подпрограммы или подпрограммы, оцениваемые только один раз, для совместного использования объектов и децентрализованной инициализации.
  • Синтаксис на основе ключевых слов в традициях ALGOL / Pascal, но без разделителей, поскольку точки с запятой являются необязательными, а синтаксис операторов доступен для подпрограмм.
  • Нечувствительность к регистру
  • Простое параллельное объектно-ориентированное программирование ( SCOOP ) облегчает создание нескольких одновременно активных средств выполнения на уровне абстракции, превышающем конкретные детали этих средств (например, несколько потоков без особого управления мьютексами).

Цели дизайна [ править ]

Эйфель делает упор на декларативные заявления, а не на процедурный код, и пытается устранить необходимость в инструкциях по ведению бухгалтерского учета.

Эйфель избегает уловок кодирования или техник кодирования, предназначенных для компилятора как подсказки по оптимизации . Цель состоит не только в том, чтобы сделать код более читаемым, но и в том, чтобы позволить программистам сконцентрироваться на важных аспектах программы, не увязая в деталях реализации. Простота Eiffel предназначена для обеспечения простых, расширяемых, многоразовых и надежных ответов на вычислительные проблемы. Компиляторы для компьютерных программ, написанных на Eiffel, предоставляют обширные методы оптимизации, такие как автоматическое встраивание, которые освобождают программиста от части бремени оптимизации.

Фон [ править ]

Eiffel изначально был разработан Eiffel Software, компанией, основанной Бертраном Мейером . Построение объектно-ориентированного программного обеспечения содержит подробное описание концепций и теории объектной технологии, которые привели к созданию Эйфеля. [7]

Цель разработки, лежащая в основе языка Eiffel, библиотек и методов программирования, - дать программистам возможность создавать надежные, повторно используемые программные модули. Eiffel поддерживает множественное наследование , универсальность , полиморфизм , инкапсуляцию , безопасные преобразования типов и ковариацию параметров . Самый важный вклад Эйфеля в разработку программного обеспечения - это проектирование по контракту (DbC), в котором утверждения , предварительные условия , постусловия и инварианты классов используются для обеспечения корректности программы без ущерба для эффективности.

Дизайн Эйфеля основан на теории объектно-ориентированного программирования с незначительным влиянием других парадигм или заботой о поддержке устаревшего кода. Eiffel формально поддерживает абстрактные типы данных . По замыслу Эйфеля, программный текст должен иметь возможность воспроизводить свою проектную документацию из самого текста, используя формализованную реализацию «абстрактного типа данных».

Реализации и среды [ править ]

EiffelStudio - это интегрированная среда разработки, доступная по лицензии с открытым исходным кодом или по коммерческой лицензии. Он предлагает объектно-ориентированную среду для разработки программного обеспечения . EiffelEnvision - это надстройка для Microsoft Visual Studio, которая позволяет пользователям редактировать, компилировать и отлаживать проекты Eiffel из среды Microsoft Visual Studio IDE. Доступны пять других реализаций с открытым исходным кодом : Tecomp "The Eiffel Compiler"; Гобо Эйфель; SmartEiffel , реализация GNU, основанная на более старой версии языка; LibertyEiffel , основанный на компиляторе SmartEiffel; и Visual Eiffel .

Некоторые другие языки программирования включают элементы, впервые представленные в Eiffel. Sather , например, изначально был основан на Eiffel, но с тех пор разошелся и теперь включает несколько функций функционального программирования . Язык интерактивного обучения Blue, предшественник BlueJ , также основан на Eiffel. Компании Apple Media Tool включает в Eiffel основе Apple , медиа Язык.

Спецификации и стандарты [ править ]

Определение языка Eiffel является международным стандартом ISO . Стандарт был разработан ECMA International , которая впервые утвердила стандарт 21 июня 2005 г. как Стандарт ECMA-367, Eiffel: язык анализа, проектирования и программирования. В июне 2006 года ECMA и ISO приняли вторую версию. В ноябре 2006 года ISO впервые опубликовала эту версию. Стандарт можно найти и бесплатно использовать на сайте ECMA. [8] Версия ISO [9] идентична во всех отношениях, за исключением форматирования.

Eiffel Software, Tecomp "Eiffel Compiler" и разработчик библиотеки Eiffel Gobo взяли на себя обязательство внедрить стандарт; EiffelStudio 6.1 и «Компилятор Eiffel» Tecomp от Eiffel Software реализуют некоторые из основных новых механизмов, в частности, встроенные агенты, команды присваивания, скобочную нотацию, несоответствующее наследование и присоединенные типы. Команда SmartEiffel отвернулась от этого стандарта, чтобы создать свою собственную версию языка, которая, по их мнению, ближе к оригинальному стилю Eiffel. Object Tools не раскрывает, будут ли будущие версии его компилятора Eiffel соответствовать стандарту. LibertyEiffel реализует диалект где-то посередине между языком SmartEiffel и стандартом.

Стандарт цитирует следующие предшествующие спецификации языка Eiffel:

  • Бертран Мейер: Eiffel: The Language, Prentice Hall, вторая печать, 1992 г. (первая печать: 1991 г.)
  • Бертран Мейер: Standard Eiffel (пересмотр предыдущей статьи), текущий, 1997 - настоящее время, на странице Бертрана Мейера в ETL3, и
  • Бертран Мейер: Построение объектно-ориентированного программного обеспечения, Prentice Hall: первое издание, 1988; Издание второе, 1997 г.
  • Бертран Мейер: Прикосновение к классу: учимся хорошо программировать с объектами и контрактами, Springer-Verlag, 2009 ISBN  978-3-540-92144-8 lxiv + 876 страниц Полноцветная печать, многочисленные цветные фотографии

Текущая версия стандарта от июня 2006 г. содержит некоторые несоответствия (например, ковариантные переопределения) [ необходима ссылка ] . Комитет ECMA еще не объявил никаких сроков и указаний по устранению несоответствий.

Синтаксис и семантика [ править ]

Общая структура [ править ]

«Система» или «программа» Эйфеля - это набор классов . Выше уровня классов Eiffel определяет кластер , который по сути представляет собой группу классов и, возможно, подкластеров (вложенных кластеров). Кластеры - это не синтаксическая языковая конструкция , а скорее стандартное организационное соглашение. Обычно программа Eiffel организована с каждым классом в отдельном файле, а каждый кластер - в каталоге, содержащем файлы классов. В этой организации подкластеры - это подкаталоги. Например, в соответствии со стандартными организационными соглашениями и соглашениями о корпусе это x.eможет быть имя файла, который определяет класс с именем X.

Класс содержит функции , похожие на «процедуры», «члены», «атрибуты» или «методы» в других объектно-ориентированных языках программирования. Класс также определяет свои инварианты и содержит другие свойства, такие как раздел «примечания» для документации и метаданных. Стандартные типы Эйфель данных, такие как INTEGER, STRINGи ARRAY, все сами классы.

В каждой системе должен быть класс, обозначенный как «root», а одна из процедур его создания - как «корневая процедура». Выполнение системы состоит из создания экземпляра корневого класса и выполнения его корневой процедуры. Как правило, при этом создаются новые объекты, вызываются новые функции и т. Д.

У Eiffel есть пять основных исполняемых инструкций: назначение, создание объекта, вызов подпрограммы, условие и итерация. Управляющие структуры Eiffel строго следят за соблюдением структурного программирования: каждый блок имеет ровно одну запись и ровно один выход.

Обзор [ править ]

В отличие от многих объектно-ориентированных языков, но, как и Smalltalk , Eiffel не допускает присвоения атрибутов объектов, за исключением функций объекта, что является практическим применением принципа сокрытия информации или абстракции данных, требующего формальных интерфейсов для данных. мутация. Чтобы перевести его на язык других объектно-ориентированных языков программирования, все атрибуты Eiffel являются «защищенными», а для клиентских объектов необходимы «установщики» для изменения значений. Результатом этого является то, что «установщики» могут и обычно реализуют инварианты, для которых Eiffel предоставляет синтаксис.

Хотя Eiffel не разрешает прямой доступ к функциям класса клиенту класса, он допускает определение «команды назначителя», например:

 some_attribute :  SOME_TYPE  назначить  set_some_attribute  set_some_attribute  ( v :  VALUE_TYPE )  - Установить значение some_attribute равным `v '.  сделать  some_attribute  : =  v  конец

Несмотря на небольшой поклон всему сообществу разработчиков, позволяющее разрешить что-то похожее на прямой доступ (например, тем самым нарушая принцип сокрытия информации), такая практика опасна, поскольку она скрывает или затемняет реальность использования «установщика». На практике лучше перенаправить вызов сеттеру, чем предполагать прямой доступ к функции, some_attributeкак в приведенном выше примере кода.

В отличие от других языков, имеющих понятия «общедоступный», «защищенный», «частный» и т. Д., Eiffel использует технологию экспорта, чтобы более точно контролировать область видимости между классами клиента и поставщика. Видимость функции проверяется статически во время компиляции. Например, (ниже) "{NONE}" аналогично слову "protected" в других языках. Область применения, примененная таким образом к «набору функций» (например, все, что находится ниже ключевого слова «характеристика» до следующего ключевого слова набора функций или конца класса), может быть изменена в классах-потомках с помощью ключевого слова «экспорт».

feature  { NONE }  - Инициализация default_create - Инициализировать новый "нулевой" десятичный экземпляр. сделать make_zero end

В качестве альтернативы, отсутствие экспортной декларации {x} подразумевает {ЛЮБОЙ} и аналогично "общедоступной" области видимости других языков.

особенность  - Константы

Наконец, область видимости можно выборочно и точно контролировать для любого класса во вселенной проекта Eiffel, например:

функция  { DECIMAL ,  DCM_MA_DECIMAL_PARSER ,  DCM_MA_DECIMAL_HANDLER }  - Доступ

Здесь компилятор разрешит только классам, перечисленным в фигурных скобках, получить доступ к функциям в группе функций (например , DECIMAL, DCM_MA_DECIMAL_PARSER, DCM_MA_DECIMAL_HANDLER ).

"Привет, мир!" [ редактировать ]

Внешний вид языка программирования часто передается с помощью "Hello, world!" программа. Такая программа, написанная на Eiffel, может быть:

class  HELLO_WORLD create  make feature  make  do  print  ( "Hello, world!% N" )  end end

Эта программа содержит класс HELLO_WORLD. Конструктор (подпрограмма создания) для класса с именем makeвызывает printподпрограмму системной библиотеки для записи "Hello, world!"сообщения в вывод.

Дизайн по контракту [ править ]

Концепция дизайна по контракту занимает центральное место в Eiffel. Контракты утверждают, что должно быть истинным до выполнения подпрограммы (предварительное условие), а что должно выполняться, чтобы быть истинным после завершения подпрограммы (постусловие). Контракты инварианта класса определяют, какие утверждения должны выполняться до и после доступа к любой функции класса (как к процедурам, так и к атрибутам). Более того, контракты кодифицируют в исполняемом коде предположения разработчиков и дизайнеров об операционной среде функций класса или класса в целом с помощью инварианта.

Компилятор Eiffel предназначен для включения контрактов функций и классов на различных уровнях. EiffelStudio, например, выполняет все контракты функций и классов во время выполнения в «режиме Workbench». Когда исполняемый файл создается, компилятор получает указание через файл настроек проекта (например, файл ECF) включить или исключить любой набор контрактов. Таким образом, исполняемый файл может быть скомпилирован для включения или исключения любого уровня контракта, тем самым обеспечивая непрерывные уровни модульного и интеграционного тестирования. Более того, контракты могут выполняться непрерывно и методично с помощью функции автотеста в EiffelStudio.

Механизмы проектирования по контракту тесно интегрированы с языком и руководят переопределением функций в наследовании:

  • Обычное предварительное условие: предварительное условие может быть ослаблено только наследованием; любой вызов, отвечающий требованиям предка, соответствует требованиям потомка.
  • Обычное постусловие: Постусловие может быть усилено только наследованием; любой результат, гарантированный предком, по-прежнему предоставляется потомком.
  • Инвариант класса: условия, которые должны выполняться после создания объекта и после любого вызова экспортированной подпрограммы класса. Поскольку инвариант проверяется так часто, это делает его одновременно и самой дорогой, и самой мощной формой условия или контракта.

Кроме того, язык поддерживает «инструкцию проверки» (своего рода «утверждение»), инварианты цикла и варианты цикла (которые гарантируют завершение цикла).

Способность к защите от пустоты [ править ]

Возможности Void-safe, такие как статическая типизация, - еще одно средство повышения качества программного обеспечения. Безопасное программное обеспечение защищено от ошибок времени выполнения, вызванных вызовами недействительных ссылок , и, следовательно, будет более надежным, чем программное обеспечение, в котором могут происходить вызовы пустых целей. Полезна аналогия со статической типизацией. Фактически, возможность защиты от пустот можно рассматривать как расширение системы типов или шаг за пределы статической типизации, потому что механизм обеспечения безопасности пустот интегрирован в систему типов.

Защиту от недействительных целевых вызовов можно увидеть с помощью понятий присоединения и (по расширению) отсоединения (например, ключевое слово detachable). Пустотно-безопасное средство можно увидеть в короткой переработке приведенного выше примера кода:

 some_attribute :  съемный  SOME_TYPE  use_some_attribute  - Установить значение some_attribute равным `v '.  делать,  если  какой-то атрибут прикреплен  как l_attribute, затем do_something ( l_attribute ) end end         do_something  ( a_value :  SOME_TYPE )  - Сделайте что-нибудь с `a_value '.  делать  ...  делать  что-то  с  ` a_value '  ...  end

В приведенном выше примере кода показано, как компилятор может статически определять надежность some_attributeподключения или отключения в момент использования. Примечательно, что attachedключевое слово допускает «локальное вложение» (например l_attribute), область действия которого ограничивается только блоком кода, заключенным в конструкцию if-statement. Таким образом, в этом небольшом блоке кода l_attributeможно статически гарантировать , что локальная переменная (например ) не является недействительной (т.е. является недействительной).

Возможности: команды и запросы [ править ]

Основной характеристикой класса является то, что он определяет набор функций: поскольку класс представляет набор объектов времени выполнения или «экземпляров», функция - это операция над этими объектами. Есть два типа функций: запросы и команды. Запрос предоставляет информацию об экземпляре. Команда изменяет экземпляр.

Различие команд и запросов важно для метода Эйфеля. Особенно:

  • Принцип унифицированного доступа : с точки зрения программного клиента, выполняющего вызов функции класса, не имеет значения, является ли запрос атрибутом (значением поля) или функцией (вычисляемым значением). Например, это a_vehicle.speedможет быть атрибут объекта a_vehicle, к которому осуществляется доступ , или он может быть вычислен функцией, которая делит расстояние на время. Обозначения одинаковы в обоих случаях, так что легко изменить реализацию класса, не затрагивая клиентское программное обеспечение.
  • Принцип разделения команд и запросов : запросы не должны изменять экземпляр. Это не языковое правило, а методологический принцип. Итак, в хорошем стиле Эйфеля нельзя найти функций «получить», которые что-то меняют и возвращают результат; вместо этого есть команды (процедуры) для изменения объектов и запросы для получения информации об объекте в результате предыдущих изменений.

Перегрузка [ править ]

Eiffel не допускает перегрузки аргументов . Каждое имя функции в классе всегда сопоставляется с определенной функцией в классе. Одно имя в рамках одного класса означает одно. Этот выбор дизайна помогает читаемости классов, избегая причины двусмысленности в отношении того, какая процедура будет вызвана при вызове. Это также упрощает языковой механизм; в частности, это то, что делает возможным механизм множественного наследования Эйфеля. [10]

Имена, конечно, можно повторно использовать в разных классах. Например, функция плюс (вместе с ее инфиксным псевдонимом "+" ) определена в нескольких классах: INTEGER , REAL , STRING и т. Д.

Универсальность [ править ]

Общий класс - это класс, который различается по типу (например, LIST [PHONE], список номеров телефонов; ACCOUNT [G-> ACCOUNT_TYPE], позволяющий использовать ACCOUNT [SAVINGS] и ACCOUNT [CHECKING] и т. Д.). Классы могут быть универсальными, что означает, что они параметризованы по типам. Общие параметры указаны в квадратных скобках:

 список  классов [ G ]  ...

G известен как «формальный общий параметр». (Эйфель резервирует «аргумент» для подпрограмм и использует «параметр» только для общих классов.) С таким объявлением G представляет внутри класса произвольный тип; поэтому функция может возвращать значение типа G, а процедура может принимать аргумент этого типа:

пункт :  G  сделать  ...  конец положить  ( x :  G )  сделать  ...  конец

LIST [INTEGER]И LIST [WORD]являются «общей» деривацией этого класса. Допустимые комбинации (с n: INTEGER, w: WORD, il: LIST [INTEGER], wl: LIST [WORD]) являются:

n  : =  il . элемент wl . положить  ( ш )

INTEGERи WORDявляются «фактическими универсальными параметрами» в этих универсальных производных.

Также возможно иметь «ограниченные» формальные параметры, для которых фактический параметр должен наследовать от заданного класса, «ограничение». Например, в

 класс  HASH_TABLE  [ G ,  KEY  ->  HASHABLE ]

вывод HASH_TABLE [INTEGER, STRING]действителен, только если STRINGнаследуется от HASHABLE(как это действительно происходит в типичных библиотеках Eiffel). Внутри класса, KEYограничившись HASHABLEсредствами, которые x: KEYможно применить ко xвсем функциям HASHABLE, как в x.hash_code.

Основы наследования [ править ]

Чтобы наследовать от одного или нескольких других, класс будет включать в себя inheritпредложение в начале:

класс  C  наследует  A  B- ... Объявление остальной части класса ...

Класс может переопределить (переопределить) некоторые или все унаследованные функции. Это должно быть явно объявлено в начале класса через redefineподпункт наследования, как в

класс  C  наследовать  A  переопределить  f ,  g ,  h  end  B  переопределить  u ,  v  end

См. [11] для полного обсуждения наследования Эйфеля.

Отложенные классы и функции [ править ]

Классы могут быть определены с помощью, deferred classа не с, classчтобы указать, что класс не может быть создан напрямую. Классы, не поддерживающие создание экземпляров, называются абстрактными классами в некоторых других объектно-ориентированных языках программирования. На языке Эйфеля можно создать экземпляр только «эффективного» класса (он может быть потомком отложенного класса). Функцию также можно отложить, используя deferredключевое слово вместо doпредложения. Если у класса есть какие-либо отложенные функции, он должен быть объявлен как отложенный; однако класс без отложенных функций может, тем не менее, быть отложенным.

Отложенные классы играют примерно ту же роль, что и интерфейсы в таких языках, как Java, хотя многие теоретики объектно-ориентированного программирования считают, что интерфейсы сами по себе в значительной степени являются ответом на отсутствие множественного наследования в Java (которое есть у Eiffel). [12] [13]

Переименование [ править ]

Класс, наследующий от одного или нескольких других, по умолчанию получает все свои функции под своими исходными именами. Однако он может изменить их названия с помощью renameпунктов. Это требуется в случае множественного наследования, если есть конфликты имен между унаследованными функциями; без переименования результирующий класс нарушит указанный выше принцип отсутствия перегрузки и, следовательно, будет недействительным.

Кортежи [ править ]

Типы кортежей можно рассматривать как простую форму класса, предоставляющую только атрибуты и соответствующую процедуру «установщика». Типичный тип кортежа читает

 TUPLE  [ имя :  STRING ;  вес :  НАСТОЯЩИЙ ;  дата :  ДАТА ]

и может быть использован для описания простого понятия записи о рождении, если класс не нужен. Экземпляр такого кортежа - это просто последовательность значений с заданными типами, указанными в скобках, например

 [ "Бриджит" ,  3.5 ,  Last_night ]

К компонентам такого кортежа можно получить доступ, как если бы теги кортежа были атрибутами класса, например, если tбыл назначен кортеж выше, то он t.weightимеет значение 3.5.

Благодаря понятию команды назначителя (см. Ниже), точечная нотация также может использоваться для назначения компонентов такого кортежа, как в

 т . вес  : =  т . вес  +  0,5

Теги кортежа являются необязательными, поэтому также можно записать тип кортежа как TUPLE [STRING, REAL, DATE]. (В некоторых компиляторах это единственная форма кортежа, поскольку теги были введены в стандарте ECMA.)

Точная спецификация , например , в TUPLE [A, B, C]том , что она описывает последовательности по меньшей мере , трех элементов, первые три существа типов A, B, Cсоответственно. В результате TUPLE [A, B, C]соответствует (может быть назначено) TUPLE [A, B], TUPLE [A]и TUPLE(без параметров) самому верхнему типу кортежа, которому соответствуют все типы кортежей.

Агенты [ править ]

Механизм «агента» Эйфеля превращает операции в объекты. Этот механизм можно использовать для итераций, программирования , управляемого событиями , и других контекстов, в которых полезно передавать операции по структуре программы. Другие языки программирования, особенно те, которые делают упор на функциональное программирование , допускают аналогичный шаблон с использованием продолжений , замыканий или генераторов ; Агенты Эйфеля подчеркивают объектно-ориентированную парадигму языка и используют синтаксис и семантику, аналогичные блокам кода в Smalltalk и Ruby .

Например, чтобы выполнить my_actionблок для каждого элемента , нужно my_listнаписать:

 мой_лист . do_all  ( агент  my_action )

Чтобы выполнить my_actionтолько на удовлетворяющих элементах my_condition, можно добавить ограничение / фильтр:

 мой_лист . do_if  ( агент  my_action ,  агент  my_condition )

В этих примерах my_actionи my_conditionесть подпрограммы. Приставка к ним с помощью agentдает объект, который представляет соответствующую подпрограмму со всеми ее свойствами, в частности, с возможностью вызова с соответствующими аргументами. Итак, если aпредставляет этот объект (например, потому что aэто аргумент do_all), инструкция

 а . вызов  ( [ x ] )

будет вызывать оригинальную программу с аргументом x, как если бы мы непосредственно назвали оригинальную программу: my_action (x). Здесь аргументы callпередаются в виде кортежа [x].

Можно оставить некоторые аргументы для агента открытыми, а другие сделать закрытыми . Открытые аргументы передаются в качестве аргументов call: они предоставляются во время использования агента . Закрытые аргументы предоставляются во время определения агента . Например, если action2есть два аргумента, итерация

 мой_лист . do_all  ( агент  действие2  ( ? ,  у ))

выполняет итерацию action2 (x, y)для последовательных значений x, где второй аргумент остается установленным y. Знак вопроса ?указывает на открытый аргумент; y- закрытый аргумент агента. Обратите внимание, что основной синтаксис agent f- это сокращение для agent f (?, ?, ...)всех открытых аргументов. Также возможно сделать цель агента открытой с помощью записи, {T}?где T- тип цели.

Различие между открытыми и закрытыми операндами (операнды = аргументы + цель) соответствует различию между связанными и свободными переменными в лямбда-исчислении . Выражение агента , такие как action2 (?, y)с некоторыми операндами закрытых и открытой некоторыми соответствуют версиям оригинальных операций кэррите на закрытых операндах.

Механизм агента также позволяет определить агент без привязки к существующей подпрограмме (например my_action, my_condition, action2), через встроенные агенты , как в

мой_лист . do_all  ( агент  ( s :  STRING )  требует  not_void :  s  / =  Void  do  s . append_character  ( ',' )  гарантирует  добавление :  s . count  =  old  s . count  +  1  end )

Переданный здесь встроенный агент может иметь все атрибуты обычной процедуры, включая предварительное условие, постусловие, предложение восстановления (здесь не используется) и полную подпись. Это позволяет избежать определения подпрограмм, когда все, что нужно, - это вычисления, которые должны быть заключены в агент. Это полезно, в частности, для контрактов, как в инвариантном предложении, которое выражает, что все элементы списка положительны:

 мой_лист . for_all  ( агент  ( x :  INTEGER ):  BOOLEAN  do  Result  : =  ( x  >  0 )  end )

Текущий механизм агента оставляет возможность ошибки типа времени выполнения (если процедура с n аргументами передается агенту, ожидающему m аргументов с m < n ). Этого можно избежать путем проверки времени выполнения через предварительное условие valid_argumentsо call. Доступно несколько предложений по чисто статическому исправлению этой проблемы, в том числе предложение об изменении языка Рибет и др. [14]

Once процедуры [ править ]

Результат процедуры можно кэшировать, используя onceключевое слово вместо do. Не первые вызовы подпрограммы не требуют дополнительных вычислений или выделения ресурсов, а просто возвращают ранее вычисленный результат. Распространенным шаблоном для «однократных функций» является предоставление общих объектов; первый вызов создаст объект, последующие вернут ссылку на этот объект. Типичная схема:

shared_object :  SOME_TYPE  после  создания  Result . make  ( args )  - Создает объект и возвращает ссылку на него через `Result '.  конец

Возвращенный объект - Resultв этом примере - сам может быть изменяемым, но его ссылка остается той же.

Часто «однократные подпрограммы» выполняют требуемую инициализацию: несколько вызовов библиотеки могут включать вызов процедуры инициализации, но только первый такой вызов будет выполнять требуемые действия. С помощью этого шаблона инициализацию можно децентрализовать, избегая необходимости в специальном модуле инициализации. "Once" подпрограммы аналогичны по назначению и действию шаблону singleton во многих языках программирования и шаблону Borg, используемому в Python.

По умолчанию «однократная процедура» вызывается один раз для каждого потока . Семантику можно настроить на один раз для процесса или один раз на объект , уточнив его с помощью «однократного ключа», например once ("PROCESS").

Конверсии [ править ]

Eiffel предоставляет механизм, позволяющий преобразовывать различные типы. Механизмы сосуществуют с наследованием и дополняют его. Чтобы избежать путаницы между двумя механизмами, в конструкции используется следующий принцип:

(Принцип преобразования) Тип не может одновременно соответствовать и преобразовывать в другой.

Например, NEWSPAPERможет соответствовать PUBLICATION, но INTEGERпреобразуется в REAL(и не наследует от него).

Механизм преобразования просто обобщает специальные правила преобразования (например, между INTEGERи REAL), которые существуют в большинстве языков программирования, делая их применимыми к любому типу, если соблюдается вышеуказанный принцип. Например, DATEможет быть объявлен класс для преобразования в STRING; это позволяет создать строку из даты просто через

 my_string  : =  my_date

как ярлык для использования явного создания объекта с процедурой преобразования:

 создать  my_string . make_from_date  ( моя_дата )

Чтобы первая форма стала синонимом второй, достаточно перечислить процедуру создания (конструктор) make_from_dateв convertпредложении в начале класса.

В качестве другого примера, если в списке есть такая процедура преобразования TUPLE [day: INTEGER; month: STRING; year: INTEGER], то можно напрямую присвоить кортеж дате, вызывая соответствующее преобразование, как в

 Bastille_day  : =  [ 14 ,  "июль" ,  1789 г. ]

Обработка исключений [ править ]

Обработка исключений в Eiffel основана на принципах проектирования по контракту. Например, исключение возникает, когда вызывающая подпрограмма не может удовлетворить предварительное условие или когда процедура не может гарантировать обещанное постусловие. В Eiffel обработка исключений не используется для потока управления или для исправления ошибок ввода данных.

Обработчик исключений Eiffel определяется с помощью ключевого слова rescue . В спасательной разделе, повторная попытка ключевое слово снова выполняет процедуру. Например, следующая подпрограмма отслеживает количество попыток выполнения подпрограммы и повторяет попытки только определенное количество раз:

connect_to_server  ( server :  SOCKET )  - подключиться к серверу или отказаться после 10 попыток.  требуется  server  / =  Void,  а затем  server . адрес  / =  аннулировать  локальные  попытки :  INTEGER  do  server . подключить  убедитесь, что  подключен :  сервер . is_connected  rescue,  если  попыток  <  10,  то  попыток  : =  попытки  +  1  повтор  конец  конец

Однако этот пример, вероятно, ошибочен для чего-либо, кроме простейших программ, поскольку следует ожидать сбоя соединения. Для большинства программ было бы лучше использовать имя подпрограммы, например, try_connecting_to_server , и постусловие не обещало бы соединение, оставляя вызывающей стороне возможность предпринять соответствующие шаги, если соединение не было открыто.

Параллелизм [ править ]

Доступен ряд сетевых и потоковых библиотек, таких как EiffelNet и EiffelThreads. Модель параллелизма для Eiffel, основанная на концепциях проектирования по контракту, - это SCOOP , или простое параллельное объектно-ориентированное программирование , которое еще не является частью официального определения языка, но доступно в EiffelStudio . CAMEO [15] - это (нереализованная) вариация SCOOP для Eiffel. Параллелизм также взаимодействует с исключениями. Асинхронные исключения могут быть проблематичными (когда процедура вызывает исключение после того, как ее вызывающая сторона завершила свою работу). [16]

Оператор и синтаксис скобок, команды назначения [ править ]

Взгляд Эйфеля на вычисления полностью объектно-ориентирован в том смысле, что каждая операция относится к объекту, «цели». Так, например, такое дополнение, как

а  +  б

концептуально понимается, как если бы это был вызов метода

а . плюс  ( б )

с целью a, особенностями plusи аргументами b.

Конечно, первый является обычным синтаксисом и обычно предпочтительнее. Синтаксис оператора позволяет использовать любую форму путем объявления функции (например, в INTEGER, но это применимо к другим базовым классам и может использоваться в любых других, для которых подходит такой оператор):

плюс  псевдоним  "+"  ( другое :  INTEGER ):  INTEGER  - ... Обычное объявление функции ...  конец

Диапазон операторов, которые можно использовать в качестве «псевдонимов», довольно широк; они включают предопределенные операторы, такие как «+», а также «свободные операторы», состоящие из не буквенно-цифровых символов. Это позволяет создавать специальные инфиксные и префиксные обозначения, например, в математических и физических приложениях.

Каждый класс может дополнительно иметь одну функцию с псевдонимом «[]», оператором «скобки», что позволяет использовать обозначение a [i, ...]как синоним того, a.f (i, ...)где fнаходится выбранная функция. Это особенно полезно для контейнерных структур, таких как массивы, хэш-таблицы , списки и т. Д. Например, доступ к элементу хеш-таблицы со строковыми ключами может быть записан

 number  : =  phone_book  [ "ДЖИЛЛ СМИТ" ]

«Команды-назначители» - это вспомогательный механизм, разработанный в том же духе, позволяющий переосмыслить устоявшиеся и удобные обозначения в рамках объектно-ориентированного программирования. Команды присваивания позволяют схожему с присваиванием синтаксису вызывать процедуры «установщика». Собственно назначение никогда не может иметь форму, a.x := vпоскольку это нарушает сокрытие информации; вам нужно использовать команду (процедуру) установки. Например, класс хэш-таблицы может иметь функцию и процедуру

 псевдоним  элемента «[]»  ( ключ :  СТРОКА ):  ELEMENT  [ 3 ]  - Элемент ключа `key '.  - (запрос "Getter")  do  ...  endput  ( e :  ELEMENT ;  key :  STRING )  - Вставить элемент `e ', связав его с ключом` key'.  - (команда "Сеттер")  делать  ...  конец

Затем, чтобы вставить элемент, вы должны использовать явный вызов команды setter:

 [ 4 ]  phone_book . put  ( New_person ,  "ДЖИЛЛ СМИТ" )

Это можно записать эквивалентно как

 [ 5 ]  phone_book  [ "JILL SMITH" ]  : =  New_person

(так же, как это phone_book ["JILL SMITH"]является синонимом number := phone_book.item ("JILL SMITH")), при условии, что объявление itemначала (замена для [3]) с

  псевдоним  элемента "[]"  ( ключ :  STRING ):  ELEMENT  назначить  положить

Это объявляется putкак команда присваивания, связанная с itemи, в сочетании с псевдонимом скобок, делает [5] допустимым и эквивалентным [4]. (Его также можно было бы записать, не используя скобку, как phone_book.item ("JILL SMITH") := New_person.

Примечание: список аргументов присваивающего a должен быть следующим: (возвращаемый тип a; весь список аргументов a ...)

Лексические и синтаксические свойства [ править ]

В Eiffel регистр не учитывается. Лексемы make, maKeи MAKEвсе обозначают один и тот же идентификатор. См., Однако, «правила стиля» ниже.

Комментарии начинаются --(два последовательных тире) и доходят до конца строки.

Точка с запятой, как разделитель инструкций, не обязательна. В большинстве случаев точка с запятой просто опускается, за исключением разделения нескольких инструкций в строке. В результате на странице программы меньше беспорядка.

Нет вложенности объявлений функций и классов. В результате структура класса Eiffel проста: некоторые предложения уровня класса (наследование, инвариант) и последовательность объявлений функций - все на одном уровне.

Принято группировать функции в отдельные «разделы функций» для большей читабельности, при этом стандартный набор тегов основных функций появляется в стандартном порядке, например:

класс  HASH_TABLE  [ ELEMENT ,  KEY  ->  HASHABLE ]  наследовать  TABLE  [ ELEMENT ] особенность  - Инициализация  - ... Объявления команд инициализации (процедуры / конструкторы создания) ... особенность  - Доступ  - ... Объявления небулевых запросов о состоянии объекта, например, элемент ... особенность  - Отчет о состоянии  - ... Объявления логических запросов о состоянии объекта, например is_empty ... особенность  - Изменение элемента  - ... Объявления команд, изменяющих структуру, например, положить ... - и т. д. конец

В отличие от большинства языков программирования с фигурными скобками , Eiffel проводит четкое различие между выражениями и инструкциями. Это соответствует принципу разделения команд и запросов метода Эйфеля.

Соглашения о стилях [ править ]

Большая часть документации Eiffel использует отличительные соглашения о стилях, разработанные для обеспечения единообразия внешнего вида. Некоторые из этих соглашений применяются к самому формату кода, а другие - к стандартной типографской визуализации кода Эйфеля в форматах и ​​публикациях, где эти соглашения возможны.

Хотя язык нечувствителен к регистру, стандарты стиля предписывают использование заглавных букв для имен классов ( LIST), строчных букв для имен функций ( make) и начальных заглавных букв для констант ( Avogadro). Рекомендуемый стиль также предлагает подчеркивание для разделения компонентов многословного идентификатора, например average_temperature.

Спецификация Eiffel включает рекомендации по отображению программных текстов в форматах набора: ключевые слова выделены жирным шрифтом, пользовательские идентификаторы и константы показаны в italics, комментарии, операторы и знаки препинания внутри Roman, с текстом программы, blueкак в настоящей статье, чтобы отличить его от пояснительный текст. Например, «Привет, мир!» приведенная выше программа будет отображаться в документации Eiffel, как показано ниже:

class  HELLO_WORLD create  make feature  make  do  print  ( "Hello, world!" )  end end

Интерфейсы с другими инструментами и языками [ править ]

Eiffel - это чисто объектно-ориентированный язык, но он обеспечивает открытую архитектуру для взаимодействия с «внешним» программным обеспечением на любом другом языке программирования.

Например, на языке C можно программировать операции на уровне машины и операционной системы . Eiffel предоставляет простой интерфейс для подпрограмм C, включая поддержку «встроенного C» (написание тела подпрограммы Eiffel на C, обычно для коротких операций на уровне машины).

Несмотря на то, что нет прямой связи между Eiffel и C, многие Eiffel компиляторами ( Визуальная Eiffel является одним исключением) Выход C исходного кода в качестве промежуточного языка , представить компилятор С , для оптимизации и портативности . Таким образом, они являются примерами транскомпиляторов . Tecomp компилятора Eiffel может выполнять код Eiffel напрямую (как интерпретатор) без прохождения через промежуточный код C или испускать код C, который будет передан компилятору C для получения оптимизированного нативного кода. В .NET компилятор EiffelStudio напрямую генерирует код CIL (Common Intermediate Language). SmartEiffelкомпилятор также может выводить байт-код Java .

Ссылки [ править ]

  1. ^ "Эйфель в двух словах" . archive.eiffel.com . Проверено 24 августа 2017 года .
  2. ^ "EiffelStudio 19.05 уже доступна!" . Eiffel.org .
  3. ^ "Выпуски EiffelStudio 20.11" . Eiffel.org .
  4. ^ Купер, Питер (2009). Начало Ruby: от новичка до профессионала . Начиная от новичка до профессионала (2-е изд.). Беркли: АПресс. п. 101. ISBN 978-1-4302-2363-4. В меньшей степени Python, LISP, Eiffel, Ada и C ++ также повлияли на Ruby.
  5. ^ «Эйфель - язык» . Дата обращения 6 июля 2016 .
  6. ^ Формальные языки спецификации: Eiffel, денотационная семантика, Венский метод разработки, нотация абстрактных машин, сеть Петри, общие книги, 2010
  7. ^ Построение объектно-ориентированного программного обеспечения , второе издание, Бертран Мейер , Prentice Hall, 1997, ISBN 0-13-629155-4 
  8. ^ ECMA International: Стандарт ECMA-367 - Eiffel: язык анализа, проектирования и программирования, 2-е издание (июнь 2006 г.); доступно на сайте www.ecma-international.org/publications/standards/Ecma-367.htm
  9. ^ Международная организация по стандартизации: Стандарт ISO / IEC DIS 25436, доступно на сайте [1]
  10. ^ Бертран Мейер: Перегрузка против объектной технологии, в Journal of Object-Oriented Programming (JOOP), vol. 14, вып. 4 октября – ноябрь 2001 г., доступно онлайн
  11. ^ «9 НАСЛЕДОВАНИЕ» . Archive.eiffel.com. 1997-03-23 . Проверено 8 июля 2013 .
  12. ^ «Множественное наследование и интерфейсы» . Artima.com. 2002-12-16 . Проверено 8 июля 2013 .
  13. ^ «Множественное наследование - не зло» . C2.com. 2007-04-28 . Проверено 8 июля 2013 .
  14. ^ Филипп Рибет, Сирил Адриан, Оливье Зендра, Доминик Колне: Соответствие агентов на языке Эйфеля , в Journal of Object Technology , vol. 3, вып. 4, апрель 2004 г., специальный выпуск: TOOLS USA 2003, стр. 125–143. Доступно на странице статьи JOT
  15. ^ Брук, Филипп; Ричард Пейдж (2008). «Cameo: альтернативная модель параллелизма для Eiffel» (PDF) . Формальные аспекты вычислений . Springer. 21 (4): 363–391. DOI : 10.1007 / s00165-008-0096-1 .
  16. ^ Брук, Филипп; Ричард Пейдж (2007). «Исключения в параллельном Eiffel» . Журнал объектных технологий . 6 (10): 111–126. DOI : 10.5381 / jot.2007.6.10.a4 .

Внешние ссылки [ править ]

  • Веб-сайт Eiffel Software компании, представившей Eiffel, назывался Interactive Software Engineering (ISE).