Ајфел (програмски језик)

Из Википедије, слободне енциклопедије
Ајфел
Модел објектно-оријентисан
Појавио се 1986
Аутор(и) Бертранд Мајер и Ајфел Софтвер
Дизајнер(и) Бертранд Мајер
Имплементације АфјелСтудио, СлободниАјфел, ПаметниАјфел, ВизуалниАјфел, Гобо Ајфел, "Ајфел компилатор" текомп
Утицаји Ада, Симула, Z
Утицао на Ада 2012, Албатрос, C#, D, Јава, Lissac, Racket, Руби,[1] Sather, Скала

Ајфел је ИСО-стандаризован, објектно-оријентисан програмски језик дизајниран од стране Бетранда Мајера (заговорник објектне-оријентације и аутор Конструкције објектно-оријентисаног софтвера) и Ајфел софтвер. Дизајн језика је најближе повезан са методом Ајфел програмирања. Оба су базирана на скупу принципа, укључујући дизајн по уговору, одвајањем команде упита, принцип јединственог-приступа, принцип једноставног-избора, отворено-затворени принцип, и опција-операнд раздвајања.

Многи концепти првобитно представљени преко Ајфела касније су дошли до Јаве, С#, и осталих језика[2]. Нове идеје дизајна језика, посебно кроз Екма/ИСО стандарзациони процес, настављају да буду инкорпорисани у Ајфел језик.

Карактеристике[уреди]

Кључне карактеристике Ејфел језика укључују:

  • Објектно-оријентисана структура програма у којој класа служи као класичан члан декомпозиције .
  • Дизајн по уговору чврсто интегрисан са осталим језичким конструкцијама
  • Аутоматско управљање меморијом, обично се спроводи колекција отпадака.
  • Наслеђивање, укључујући вишеструко наслеђивање, преименовање, редефинисање, "изаберите", неусаглашено наследство, и други механизми намењених за сигурно наследство .
  • Ограничено и неограничено генеричко програмирање
  • Јединствени тип система који управља вредностима и референтном семантиком у којима су све врсте, укључујући основне врсте, као што су цели бројеви, су класе на бази.
  • Статично куцање
  • Безбедност празнине, или статичка заштита од позива на нулте референце, кроз механизам приложених-типова.
  • Агенти, или објекти који обухватају израчунавања, блиско повезани са затварањем и ламбда израчунавањем.
  • Када рутине, или рутину процењују само једном, за дељење објекта и децентрализоване иницијализације.
  • Кључна реч-заснована на синтакси у АЛГОЛ / Паскал традицији, али слобнодног-раздвакача, утолико што зарез је необавезан, са синтаксом оператера доступним за рутине.
  • Случај неосетљивости
  • Једноставно Истовремено Објектно-оријентисано програмирање (SCOOP) олакшава стварање више, истовремено активних извршења возила на нивоу апстракције изнад специфичних детаља ових возила (нпр више нити без конкретног управљања мутексом).

Циљеви дизајна[уреди]

Ајфел наглашава декларативне наредбе преко процедурног кода и покушава да елиминише потребу за књиговодством упустава.

Ајфел избегава трик кодове или технике кодова намењене за оптимизацију савета компилатора. Циљ није само да се код учини читљивијим, али такође да дозволи програмерима да се концетришу на важне аспекте програма да се заглаве у детаљима имплементације. Ајфелова једноставност је намењена да промовише једноставне, прошириве, поново користиве и поуздане одговоре рачунарских проблема. Компилатори за рачунарске проблеме написани у Ајфелу пружају изванредне технике оптимизације, као што је аутоматско облагање, који ослобађа програмера од дела оптимизације терета.

Позадина[уреди]

Ајфел је оргинално развијен преко Ајфел софтвера, компанија основана од стране Бертранда Мајера. Софтвер објектно-оријентисане конструкције садржи детаљан третман концепата и теорије о објектној технологији која је довела до Ајфеловом дизајна.[3]

Циљ дизајна иза Ајфеловог језика, библиотека, и метода програмирања је да омогући програмерима да направе поузданане, поново користиве модуле софтвера. Ајфел подржава више наследства, генеричко програмирање, полиморфизам, енкапсулацију, и параметарску покривеност. Ајфелова најважнија донација софтверском инжењерству је дизајн по уговору (ДбЦ), у коме потврде, предуслови, постуслови и варијанте класи су направљене да осигурају тачност програма без жртвовања ефикасности.

Ајфелов дизајн је базиран на теорији објектно-оријентисаног програмирања, са само већим утицајем других парадигми или забринутости за подршку застарелог кода. Ајфел формално подржава апстрактне типове података. Под Ајфеловим дизајном, текст је требало да буде у могућности да производи свој дизајн документације из текста, користећи формализовану имплементацију "Апстрактни тип података".  

Имплементације и окружења[уреди]

АјфелСтудио је интегрисано развојно окружење доступно преко отвореног кода или комерцијалне лиценце. Омогућује објектно оријентисано окружење за софтверско инжењерство. АјфелЕнвижн је додатак за Мајкрософт Вижуал Студио који дозвољава корисницима да уређују, састављају и дебагују Ајфелове пројекте из Мајскрософтовог Вижуал Студиа ИДЕ. Пет осталих отворених кодова имплементација су доступни: "Ајфелов Компилатор" тецомп, Гобо Ајфел, ПаметниАјфел—ГНУ имплементација, базирана на старијим верзијама језика—, СлободниАјфел—базиран на компилатору ПаметногАјфела— и Визујелни Ајфел.

Неколико осталих програмских језика уграђују елементе први пут претстављене у Ајфелу. Sather, на пример, је оригинално базиран на Ајфелу али се скоро раширио, и сада укључује неколико карактеристика функционалног програмирања. Интерактивни-учитељски језик Блуе, претходник од БлуеЈ, је такође базиран на Ајфелу. Епл алатка медиа укључује Епл медиа језик базиран на Ајфелу.

Спецификације и стандарди[уреди]

Дефиниција Ајфел језика је интернационални стандард ИСО-а. Стандард је развио ЕЦМА Интернационал, који је први дозволио стандард 21-ог Јуна 2005 као Стандард ЕЦМА-367, Ајфел: Анализа, Дизајн и Програмски Језик. Јуна 2006-те, ЕЦМА и ИСО су усвојили другу верзију. Новембра 2006-те, ИСО је први пут објавио ту верзију. Стандард може бити нађен и бесплатно коришчен на ЕЦМА сајту.[4] ИСО верзија[5] је идентична у сваком смислу осим у форматирању.

Ајфел софтвер, "Ајфел Компилатор" текомп и развојник Ајфелове-библиотеке  Гобо је починио имплементовање стандарда; Ајфел софтвер АјфелСтудио 6.1 и "Ајфел Компилатор" текомп је имплементовао неке нове механизме —тачније, дворедни агенти, додељивачи команди, носач нотација, неусаглашено наследство и прикачене типове. ПаметниАјфел теам се склонио од овог стандарда како би креирао своју верзију језика, за коју верују да је близа оригиналном стилу Ајфела. Објекти алата нису откривени иако будуће верзије Ајфел компилатора ће бити са стандардом. СлободниАјфел имплементује дијалекат негде између ПаметногАјфела језика и стандарда. 

Стандард наводи следеће, предходник спецификације Ајфеловог-језика:

  • Бертранд Мајер: Ајфел: Језик, Прентис Хол, друго издање, 1992 (прво издање: 1991)
  • Бертранд Мајер: Стандарди Ајфел (поновна верзија претходног уноса), одлазећи, 1997–данас, на Бертранд Мајеровој ETL3 страници , i
  • Бертранд Мајер: Конструкција објектно-оријентисаног софтвера, Прентис Хол: прва едиција, 1988; друга едиција, 1997.
  • Бертранд Мајер: Додирни класу: Учење за добро програмирање са објектима и уговорима, Спрингер-Верлаг, 2009 ISBN 978-3-540-92144-8 lxiv + 876 страна штампања у пуној боји, нумерисане фотографије у боји

Тренутна верзија стандарда из Јуна 2006 садржи неке недоследности (нпр. коваријантне редефиниције). ЕЦМА комитет није још прогрласио било коју временску линију и дирекцију како решити те недоследности. 

Синтакса и семантика[уреди]

Укупна структура[уреди]

Ајфелов "систем" или "програм" је колекција класа. Изнад ниво класа, Ајфел дефинише кластер, који је суштински група класа, и могуће подкластер (угњежђени кластери). Кластери нису језичка синтаксна конструкција, већ стандардна организациона конвеција. Типично Ајфел програм ће бити организован са сваком класом у различитим фајловима, и сваки кластер у директоријум садржећи фајлове класе. У овој организацију, подкластери су поддиректоријуми. На пример, под стандардним организационим и конвецијама футрола,  x.e може бити име фајла који дефинише класу под именом X.

Класа садржи карактеристике, који су слични "рутинама", "члановима", "атрибутима" или "методама" у објектно-оријентисаним програмским језицима. Класа такође дефинише њене инваријанте, и садржи друге особине, као што су "белешке" секција за документацију и метаподатке. Ајфелови стандарди типа података, као што су  INTEGER, STRING иARRAY, су сви сами од себе класе.

Сваки систем мора имате класу означену као "корен", са једном од његових креација процедура означених као "корен процедуре". Извршење система се састоји од стварања инстанце корена класе и извршење корена процедуре. Обично, радећи то ствара нове објекте, позива нове карактеристике, и тако даље. 

Ајфел има пет класичних инструкција извршења: додела, креирање објекта, позив рутине, услов и понављање. Ајфелове стуктуре контроле су стриктне у спровођењу структурног програмирања: сваки блок има тачно један улаз и тачно један излаз.

Одређивање оквира[уреди]

За разлику од многих објкетно-оријентисаних језика, али као Smalltalk, Ајфел не дозвољава било коју доделу унутар поља објекта, осим унутар карактеристика објекта, који је практична апликација принципа скривања информација или апстракција података, захтевајући формална сучеља за мутацију података. Да би ставио у језик других објектно-оријентисаних програмских језика, сва Ајфелова поља су "приватна", и "постављачи" треба да модификују вредности. Поента све овога је да "постављачи" могу, и обично раде, имплементовање инваријанти за које Ајфел даје синтаксу.

Док Ајфел не дозвољава директан пристум карактеристикама класе од стране клијента класе, оно дозвољава дефиницију "команде додељивања", као што је:

   some_attribute: SOME_TYPE assign set_some_attribute
   
   set_some_attribute (v: VALUE_TYPE)
               -- Set value of some_attribute to `v'.
           do
               some_attribute := v
           end

Док благи наклон на укупну заједницу програмера да дозволе да нешто изгледа лепо као директни приступ (нпр. разбијање принципа сакривања информација), пракса је опасна пошто она крива или замрачује реалност "постављача" који се користи. У пракси, боље је читати директан позив постављача пре него подразумевање директно приступа карактеристици као some_attribute што је у примеру кода изнад.

За разлику од других језика, имати појмове "јавно", "приватно" и тако даље, Ајфел користи технологију извоза за прецизнију контролу одређивања поља између клиента и достављача класа. Штавише, да би се извозила логика која је коришћена може бити проверена статично преко компилатора, који дозвољава ранију детекцију одређивања поља прекршаја позива приликом компилирања пре него извршна верзија. На пример, (доле), "{NONE}" је слично "приватном" у другим језицима. Примењена област на овај начин на "групу карактеристика" (нпр. све испод кључне речи "карактеристика" или до следеће карактеристике групе кључних речи или до краја класа) може бити измењен у потомку класа користећи кључну реч  "извоз".

feature {NONE} -- Иницијализација
	default_create
			-- Иницијализује нову `нулту' инстанцу децимале.
		do
			make_zero
		end

Алтернативно, недостатак {x} извоз декларације подразумева {ANY}и сличан је области "јавно" других језика.

feature -- Константе

Коначно, одређивање области може бити селективно и прецизно контролисано при свакој класи у Ајфеловом пројектном универзуму, као што је:

feature {DECIMAL, DCM_MA_DECIMAL_PARSER, DCM_MA_DECIMAL_HANDLER} -- Приступ

Овде, компилатор ће да дозволи само класе наведене између витичастих заграда да би се приступило карактеристикама унутар групе карактеристика (нпр. DECIMAL, DCM_MA_DECIMAL_PARSER, DCM_MA_DECIMAL_HANDLER).

"Hello, world!"[уреди]

Изглед и осећај програмског језика се често преноси користећи "Hello, world!" програм. Такав програм писан у Ајфелу може бити:

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

Овај програм садржи класу HELLO_WORLD. Конструктор (направи рутину) за класу, назван make, призива  print рутину системске библиотеке да напише"Hello, world!" поруку за излаз.

Дизајн по уговору[уреди]

Концепт дизајна по уговору је главни за Ајфел. Уговори потврђују шта мора бити тачне пре него што је рутина извршена (предуслов) и шта мора чекати да буде тачно након што се рутина заврши (пост-услов). Уговори инваријанте класе дефинишу шта потврде морају држати обема тачним пре и након што је приступљено карактеристикама класе (обемама рутинама и атрибутима). Штавише, уговори се шифрују у извршујући код програмера и дизајнерових потврда о оперативном окружењу карактеристика класе у целини преко значења инваријанти.

Ајфелов компилатор је дизајниран да садржи карактеристику и класу уговора у различитим нивоима. АјфелСтудио, на пример, извршава све карактеристике и класе уговора, током извршавања у "Режиму радног стола". Када је извршење створено, компилатор је упућен путем пројекта особина фајла (нпр. ECF фајл) да или укључује или искључује било коју групу уговора. На тај начин, извршени фајл може бити састављен да или укључује или искључује било који ниво уговора, тиме доводећи континуиране нивое јединице и тестирање интеграције. Штавише, уговори могу бити континуирано и методички остварени путем карактеристике  Auto-Test нађене у АјфелСтудију.

Механизми дизајна по уговору су уско интегрисани са језиком и водичем редефинисања карактеристика у наслеђивању:

  • Предуслов рутине : Предуслов може бити ослабљен само преко наслеђивања; сваки позив који се сретне са условима предка сретне оне од потомка 
  • Постуслов рутине: Постуслоб може бити ојачан само помоћу наслеђивања; сваки гарантовани резултат од стране предка је идаље омогућен преко потомка.
  • Инваријанта класе: Услови који морају држати тачни оба пре (осим пре креирања) и после (осим пост-уништавања) приступа карактеристици класе (рутине или атрибута). Зато што је инваријанта проверена често, чини га истовремено најскупљом и најјачом формом услова или уговора.

Поред тога, језик подржава "инструкцију провере" (тип "потврде") и инваријанте петље.

Сигурност-празнине[уреди]

Празнина-сигурност, као статично куцање, је још један објекат за побољшање квалитета софтвера. Празнина-сигурности софтвер је заштићен од грешака временског покретања проузрокованих преко празних позива референци, а самим тим ће бити пузданији него софтвер у коме ће се мете позива за празнину извршити. Аналогија статичном куцању је корисна. Уствари, способност празнине-сигурности се може видети као екстензија систему куцања, или корак изнад статичног куцања, зато што механизам за осигуравање празнине-сигурности је интегрисан у систем писања.

Чувар против мети позива празнине може бити виђен путем идеје прилога и (преко екстензије) одреда (нпр. одвојиве кључне речи). Објекат празнине-сигурности може бити виђен у кратком поновном ради примера кода коришћеном изнад:

   some_attribute: detachable SOME_TYPE
   
   use_some_attribute
               -- Поставља вредност some_attribute на `v'.
           do
               if attached some_attribute as l_attribute then
                   do_something (l_attribute)
               end
           end
   
   do_something (a_value: SOME_TYPE)
               -- Ради нешто са `a_value'.
           do
              ... ради нешто са `a_value' ...
           end

Пример кода изнад показује како компилатор може статичо адресовати пузданост да ли ће some_attribute бити прикачени или откачени у тачки која се користи. Наиме, attached кључна реч дозвољава за "прилог локалне" (нпр. l_attribute), којој је одређено поље да само блокира код ограђеног преко if-наредбе конструкције. Стога, унутар малог блок кода, локална варијабла (нпр.. l_attribute) може бити статично гарантована да је не-празна (тј. празнина-сигурности).

Детаљи, команде и упити[уреди]

Примарне карактеристике класе су те да дефинишу групу карактеристика: тако што класа репрезентује групу извршних верзија објеката, или "инстанци", карактеристика је операција над овим објектима. Постоје две врсте ових карактеристика: упити и команде. Упит даје информације о инстанцама. Команда модификује инстанцу. 

Разлика између команде и упита је важна за Ајфелов метода. Нарочито: 

  • Принцип јединственог приступа: од тачке гледишта софтвера клиент прави позив карактеристици класе, без обзира да ли је ред атрибиту (вредност поља) или функција (израчуната вредност) не би требло да прави било какву разлику. На пример a_vehicle.speed може бити атрибут приступљен над објектом a_vehicle, или се може израчунати преко функцијек која дели удаљеност временом. Израз је исти код обе класе, тако да је лако променити имплементацију класе без утицаја на софтвер клијента.
  • Принцип раздвајања команде-упита: Упити не смеју модификовати инстанце. Ово није правило језика али је методологички принцим. Тако у добро стилу Ајфела, један не налази "нађи" функцију која мења нешто и враћа резултат; уместо постоје команде (процедуре) да промене објекте, и упити да преузму информације о објектима, који произилазе и претпходних промена.

Преоптерећење[уреди]

Ајфел не дозовољава преоптерећење аргумента. Свако име карактеристике унутар класе увек мапира специфичну карактеристику унутар класе. Једно име, унутар једне класе, значи једно. Овај избор дизајна помаже у читкости класа, избегавајући двосмисленост при чему ће рутина бити покренута преко позива. Такође поједноставља механизам језика; тачније, ово чини Ајфелову механизам више наслеђивања могућим.[6]

Имена се, наравно, могу поново користити у другим класама. На пример карактеристика plus (заједно са својим уметнутим алиасом "+") је дефинисан у неколико класа: INTEGER, REAL, STRING, итд.

Генерицитет[уреди]

Генеричка класа је класа која варира у типовима (нпр. LIST [PHONE], листа бројева телефона; ACCOUNT [G->ACCOUNT_TYPE], дозвољавајући за  ACCOUNT [SAVINGS] и ACCOUNT [CHECKING], итд.). Класе могу бити генеричне, да изразе да су параметризоване преко типова. Генерички параметри се показују у коцкастим заградама: 

class LIST [G] ...

G је познат као "формални генерички параметар". (Ајфел резервише "аргумент" за рутине, и користи "параметар" само за генеричке класе.). Са оваквом декларацијом G репрезентује унутар класе произвољан тип; тако да функција може вратити вредност типа G, и рутина може узети аргумент тог типа: 

item: G do ... end
put (x: G) do ... end

 LIST [INTEGER] и LIST [WORD] су "генеричке деривације" ове класе. Дозвољене комбинације (са n: INTEGER, w: WORD, il: LIST [INTEGER], wl: LIST [WORD]) су

n := il.item
wl.put (w)

INTEGER иWORD су "стварни генерички парамтери" у овим генеричким деривацијама. Могуће је такође имати "ограничене" формалне параметре, за које стварни параметри моја наслеђивати из дате класе, "ограничен". На пример у 

   class HASH_TABLE [G, KEY -> HASHABLE]

деривација HASH_TABLE [INTEGER, STRING]је тачна само акоSTRING наслеђује од HASHABLE (као што заиста ради у типичним Ајфеловим библиотекама). Унутар класе, имајући KEY ограничен преко HASHABLE значи да за  x: KEY је могуће применити на x све карактеристикеHASHABLE, као у x.hash_code.

Основе наслеђивања[уреди]

Да би се наслеђивало из једне или више других, класа ће укључивати inherit клаузулу на почетку:

class C inherit
   A
   B

-- ... Остатак декларације класе ...

Класа може редефинисати (поништење) неке или све карактеристике наслеђивања. Ово мора бити експлицитно објављено на почетку класе кроз redefineподклаузулу клаузуле наслеђивања, као у 

class C inherit
    A
        redefine f, g, h end
    B
        redefine u, v end

Видети [7] за комплетну дискусију о Ајфеловом наслеђивању.

Одложене класе и карактеристике[уреди]

Класе могу бити дефинисане са deferred class пре него са class да показују да не морају директно да инстанцирају. Не-инстанцирајуће класе се називају апстрактним класама у неким објектно-оријентисаним програмским језицима. У Ајфеловом начину говора, само "ефективне" класе могу бити инстанциране (може бити потомак одложене класе). Карактеристика може бити такође одложена коришћењем deferred кључне речи уместо do клаузуле. Ако класа има било које одложене карактеристике мора бити декларисане као одложене; међутим, класа без одложених карактеристика може сама од себе бити одложена.

Одложене класе играју једну од истих улога као сучеља у језицима као што су Јава, иако многи објектно-оријентисани програмски теоретичари верују да су сучеља сама од себе одговори за Јавин недостатак вишеструког наслеђивања (који Ајфел има) .[8][9][10]

Преименовање[уреди]

Класа која наслеђује од једне или више других добија све њене карактеристике, по дифолту под њиховим оригиналним именима. Могу, међутим, променити њихова имена кроз rename клаузулу. Ово се захтева у случају вишеструких наслеђивања ако постоје сукоби имена између карактеристика наслеђивања; без преименовања, резултујућа класа би прекршила принцип не-преоптерећења што је горе наведено и стога ће бити неважећи. 

Торке[уреди]

Типови торки се могу видети као једноставне форме класе, пружајући само атрибуте и одговарајуће "постављач" процедуре. Типичан тип торки чита 

   TUPLE [name: STRING; weight: REAL; date: DATE]

и може се користити да опише једноставан појам податка рођења ако је класа без потребна. Таква инстанца торке је једноставна секвенца вредности са датим типовима, датим у заградама, као ово

   ["Brigitte", 3.5, Last_night]

Компонентама овакве торке може се приступити ако би тагови торки били атрибути класе, на пример ако је  t додељена торка изнад онда t.weight има вредност 3.5. Захваљујући појму команде доделе (видети испод), појам тачке се такође може користити за доделу компоненти као што је торка, као у

   t.weight := t.weight + 0.5

Тагови торки су опционални, тако да је такође могуће написати тип торки каоTUPLE [STRING, REAL, DATE]. (У неким компилаторима ово је једина форма торки, пошто су тагови представљени са ЕЦМА стандардом.)

Прецизна спецификација примера TUPLE [A, B, C] је да он описује секвенце најмање три елемента, прва три су типа A, B, C редом. Као резултат TUPLE [A, B, C] у складу са (може бити додељен) TUPLE [A, B],  TUPLE [A] и TUPLE (без параметара), топ тип торки коме сви типови торки одговарају. 

Агенти[уреди]

Ајфелов "агент" механизам пакује операције у објекте. Овај механизам може бити коришћен за итерацију, догођај-погон програмирање, и остали контекси у којима је корисно проћи операције око структуре програма. Остали програмски језици, специјално они који наглашавају функционално програмирање, дозовољавају слични шаблон користећи наставке, затвараче, или генераторе; Ајфелови агенти наглашавају објектно-оријентисану парадигму, и користе синтаксу и семантику сличну блоковима кода у Smalltalk и Руби.  

На пример, за извршавање my_action блока за сваки елемент my_list, један би писао:

   my_list.do_all (agent my_action)

Да би се извршила my_actionсамо на елементима који задовољавају my_condition, ограничење/филтер може бити додат:

   my_list.do_if (agent my_action, agent my_condition)

У овим примерима, my_action и my_condition су рутине. Фиксирањем са agent предаје објекат који претставља одговарајућу рутину са свих њеним особинама, а нарочито способност да буде позвана са добрим аргументима. Тако ако a претставља тај објекат (на пример зато што је a аргумент за do_all), инструкција

   a.call ([x])

ће позвати оригиналну рутину са аргументом x, као да смо имали директно позвану оригиналну рутину: my_action (x). Аргументи за call су прошли као торке, овде [x]. Могуће је задржати неке аргументе за агента отворене и остале затворене. Отворени аргументи пролазе као аргументи за call: они су обезбеђени у тренутку времена коришћења агента. Затворени агенти су обезбеђени у тренутку дефиниције агента. На пример, ако action2 има два аргумента, итерација

   my_list.do_all (agent action2 (?, y))

итерира action2 (x, y) за успешне вредности x, где други аргументи остали су у групи y. Знак питања ? показује отворени аргумент; y је затворени аргумент агента. Имати на уму да класична синтаксаagent f is је скраћеница од agent f (?, ?, ...) са свим отвореним аргументима. Такође је могуће направити мету отвореног агента кроз појам {T}? где јеT тип мете.

Разлика имеђу отворених и затворених операнди (операнде= аргументи + мета) одговара разлици између границе и бесплатних варијабли у ламбда калкулусу. Експресија агената као што је action2 (?, y) са неким операндима затвореним и неки отвореним одговорима верзији оригиналних операција над неким затвореним операндима.

Механизам агента такође дозвољава дефинисање агента без референце постојеће рутине (као што је my_action, my_condition, action2), кроз реда агента као у

my_list.do_all (agent (s: STRING)
     require
         not_void: s /= Void
     do
         s.append_character (',')
     ensure
         appended: s.count = old s.count + 1
     end)

У реду агента који је прошао може имати сва својства нормалне рутине, укључујући предуслов, постуслов, клаузулу спаса (не користи се овде), и пун потпис. Овиме се избегава дефинисање рутина када је све што је потребно да рачунање буде убачено у агента. Ово је корисно у посебни случајевима за уговоре, као у клаузули инваријанте која приказује да су сви елементи листе позитивни: 

   my_list.for_all (agent (x: INTEGER): BOOLEAN do Result := (x > 0) end)

Тренутни механизам агента даје могућност грешке покретања-времена (ако рутина са n аргумената је прошла до агента очекујући m аргумената са m<n). Ово се може избећи преко провере покретања-времена кроз предуслов valid_arguments call. Неколико предлоза за чисту статичну провери овог проблема је доступна, укључујући измену предлога језика преко  Ribet et al.[11]

Када рутине[уреди]

Резултат рутине може бити ухваћен коришћењем once кључне речи уместо do. Не-први позиви за рутину не захтевају додатно израчунавање или алокацију ресурса, али једноставно враћају претходно израчунати резултат. Чест шаблон за "када функције" да омогуће дељене објекте; први позив ће направити објекат, касније они ће се вратити референцу на тај објекат. Типична шема је: 

shared_object: SOME_TYPE
    once
        create Result.make (args)
             -- Ово креира објекат и враћа референцу њему кроз `Result'.
    end

Враћени објекат—Result у примеру—може сама од себе бити променљива, али њена референца остаје иста.

Често "када рутине" изврше тражену инсталацију:вишеструки позиви библиотеке могу укључивати позив иницијализације процедуре, али само први такав позив ће извршити тражене акције. Користећи шаблон иницијализације може бити децентрализован, избегавајући потребу за специјалном иницијализацијом модула. "Када рутине" су сличне сврхе и утицај на један узорак у многим програмским језицима, и за   Borg узорак коришћен у Пајтону.

По дифолту, "кад рутине" су позване једном по нити. Семантике могу бити прилагођене једном по процесу или једном по објекту квалификовањем преко "када кључ", нпр. . once ("PROCESS").

Конверзије[уреди]

Ајфел омогућује механизам да дозволи конверзије између различитих типова. Механизми постоје заједно са наслеђивањем и допуњује се. Да би се избегла било каква конфузија између два механизма, дизајн спроводи следећи принциш:  

(Принцип конверзије) Тип не може ибти и у склади и да се претвара у другу.

На пример NEWSPAPER може се конверзовати уPUBLICATION, алиINTEGER конверзује у REAL (и не наслеђује га).

Механизам конверзије једноставно генерализује у правила конверзије (као наравно између INTEGER и REAL)који постоји у већини програмских језика, чинећи их применљивим за било који тип све док је горњи принцип посматран. На примерDATE може бити декларисана да се конвертује у STRING; овиме је могуће направити стринг од датума једноставно кроз

   my_string := my_date

као пречица за коришћење експлицитног објекта креације са процедуром конверзије:

   create my_string.make_from_date (my_date)

Како би омогућили прву форму могућом као синоним за другу, она је суфицит листе креације процедуре (конструктор) make_from_date уconvert клаузулу на почетку класе. Као још један пример, ако постоји оваква конверзија процедуре наведена изTUPLE [day: INTEGER; month: STRING; year: INTEGER], онда један може директно доделити торку датуму, проузроковајући пристојну конверзију, као у

      Bastille_day := [14, "July", 1789]

Обрада изузетака[уреди]

Обрада изузетака у Ајфели је базирана на принципима дизајна преко уговора. На пример, изузетак се подиже када позивач рутине задовољава предуслов, или када рутина не може осигурати обећани постуслов. У Ајфелу, обрада изузетака није коришћена за управљање током или за исправљање грешака уноса података.

Контролер Ајфелових изузетака је дефинисан користећи rescue кључну реч. Унутар rescue секције,  retry кључна реч извршава рутину поново. На пример, следећа рутина прати број покушаја при извршењу рутине, и само се понавља одређени број пута:

connect_to_server (server: SOCKET)
      -- Конектује се на сервер или се предаје после 10 покушаја.
    require
        server /= Void and then server.address /= Void
    local
        attempts: INTEGER
    do
        server.connect
    ensure
      connected: server.is_connected
    rescue
        if attempts < 10 then
            attempts := attempts + 1
            retry
        end
    end

Овај пример је вероватно погрешан за било шта осим једноставних програма, међутим, проблем са конекцијом се очекује. За већину програма име рутинеattempt_connecting_to_server би било боље, и постуслоб не би обећао конекцију, остављајући позивачу да преузме прикладне корека ако конекција није отворена.

Конкуренција[уреди]

Број умрежавања и нити библиотека је доступан, као што је АјвелМрежа и АјфелНити. Модел конкуренције за Ајфел, базиран на концептима дизајна преко уговора, је SCOOP, или Једноставно конкуретно објектно-оријентисано програмирање, није још део официјалне дефиниције језика али је доступан у АјфелСтудију. ЦАМЕО[12] је (неимплементована)варијација СКООП-а за Ајфел. Конкуренција такође интерагује са изузетцима. Асинхрони изузеци могу бити проблематични (где рутина подиже изузетак пошто је завршио позивач своје).[13]

Оператор и носач синтаксе, додељивач команди[уреди]

Ајфелов поглед на рачунање је комплентно у смислу објектне-оријентације да је свака операција повезана за овјекат, "мету". За пример адиције као што је

a + b

је концепцијски разумљиво као да је позив методе

a.plus (b)

са метом a, карактеристика plus и аргумент b. Наравно, бивши је конценционална синтакса и обично се преферира. Оператор синтаксе га чини могућим за коришћење форме декларисањем карактеристике (на пример у  INTEGER, али ово се односи на остале класичне класе и може се користити у било ком другом са овакво прикладном операцијом):

plus alias "+" (other: INTEGER): INTEGER
        -- ... Нормална декларација функције...
    end

Опсег оператора се може користити као "алиас" је прилично широк; они укључују предефинисане операторе као што је "+"али такође "бесплатне операторе"направљени од алфанумеричких симбола. Ово чини могућим за дизајн специјалних инфиксих и префиксних појмова, на пример у математици и апликација физике.  Свака класа може у адицији имати једну функцију алијасованом преко "[]", "држач" оператор, дозвољавајући појамa [i, ...] као синоним за a.f (i, ...) где је f изабрана функција. Ово је посебно корисно за колекције структура као што су низови, листе, итд. На пример приступ елементу хаш табеле са стринг кључевима може бити записан

   number := phone_book ["JILL SMITH"]

"Команде додељивача" су механизми пратиоца дизајнирани у истом духу допуштајући, практичне појмове поново уведене у оквиру објектно-оријентисаног програмирања. Команде додељивача дозвољавају додељивање-као синтаксе да би се позвале процедуре "постављача". Правилно одступање никада не може бити у облику a.x := v пошто ово крши сакривање информацију; мора се ићи за команду постављача (процедура). На пример класа хеш табела може имати функцију и процедуру

item alias "[]" (key: STRING): ELEMENT [3]
      -- Елемент кључа `key'.
      -- ("Getter" упиз)
    do
        ...
    end

put (e: ELEMENT; key: STRING)
      -- Унети елемент `e', удруживањем са кључем `key'.
      -- ("Setter" команда)
    do
        ...
    end

Онда да би се убацио елемент мора се користити експлицитан позив код команде постављача:

   [4] phone_book.put (New_person, "JILL SMITH")

Могуће је написати ово еквивалентно са

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

(на исти начин као што је phone_book ["JILL SMITH"] синоним заnumber := phone_book.item ("JILL SMITH")), пружа декларацију item који сада почиње (замена за [3]) са

   item alias "[]" (key: STRING): ELEMENT assign put

Ово декларише put као команду додељивача повезаним са  item и, у комбинацији са носачем алијаса, чини  [5] легалним и једнаким [4]. (Може такође бити записано, без узимања користи носача, као phone_book.item ("JILL SMITH") := New_person.

напомена: Аргумент листе додељивача је ограничен да буде (као повратни тип; сви као аргументи листе...) 

Лексичка и синтаксна својства[уреди]

Ајфел није осетљив на случај. Токени make, maKe и MAKE сви означавају исти идентификатор. Видети, међутим,"правила стила" испод.

Коментари су представљени -- (две узастопне црте) и настављају се до краја линије.

Запета, као раздвајач инструкције, је опционална. Већину времена запета је изостављена, осим да раздвоји више инструкција на линији. Ово резултује мањој гужви на страници програма.

Нема нагомилавања карактеристика и декларација класе. Као резултат структура Ајфелове класе је једноставна: неки нивио-класа клаузула (наслеђивање, инваријанта) и успешне декларације карактеристика, су сви истог нивоа.

Обичај је да се групирају карактеристике у одвојене"клаузуле карактеристика" за бољу читкост, са стандардним сетом основних ознака карактеристика које се појављују у стандардом редоследу, на пример:

class HASH_TABLE [ELEMENT, KEY -> HASHABLE] inherit TABLE [ELEMENT]

    feature -- Иницијализација
         -- ... Декларација команди иницијализације (креција процедура/конструкција) ...

    feature -- Приступ
         -- ... Декларација небуловог типа података упита над објектним стањем нпр. ставка ...

    feature -- Извештај статуса
         -- ... Декларације буловог типа података упита над објектним стањем, нпр. is_empty ...

    feature -- Промена елемента
         -- ... Декларација команди који мењају структуру , e.g. put ...

    -- etc.

end

За разлику од већине витичастих носача програмских језика, Ајфел прави јасну разлику између експресија и инструкција. Ово је у реду са принципо Команда-упит одвајање Ајфеловог метода .

Стил конвенције[уреди]

Већина документације Ајфела користи карактеристичан стил конвенција, дизајниран да спроведе доследан изглед-и-осећај. Неке од ових конвенција пристају формату кода саме од себе, и остали стандардима типографије пружајући Ајфелов код у форматима и издањима где су ове конвенције могуће. 

Док је језик неосетљив на случај, стандарди стилова прописују коричшћење свих главних градова за имена класа (LIST), сви нижи-случаји за имена функција (make), и почетних главних градова за константе (Avogadro). Препоручени стил такође сугестује подвлачење да би се одвојиле компоненте вишеструког идентификатора речи,                                            као у average_temperature.

Спецификација Ајфела укључује смернице за приказивање текста софтвера у типсет форматима: кључне речи подебљане, кориснички-дефинисани идентификатори и константе су показане у italics, коментари, оператори и знакови интерпункције у,Roman, са текстом програма у blue као садашњем чланку да би се разликовао од текста објашњења. На пример, "Hello, world" програм дат изнад би био донет као у Ајфеловој документацији доле:

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

Повезивање других алата и језика[уреди]

Ајфел је чист објектно-оријентисан језик али даје отворену архитектуру за повезивање са "спољним" сотфтвером у било ком другом програмском језику.

Могуће је на пример програмирати машину - и ниво операција оперативног-система у С. Ајфел пружа једноставно повезивање са С рутинама, укључујући подршку за "у реду С" (писајући тело Ајфелове рутину у С, типично за кратке нивоа-машина операције).

Иако не постоји директна веза између Ајфела и  С, много Ајфелови компилатори(Визуелни Ајфел је један изузетак) избацују С изворни код као међујезик,  да се оповргне С компилатор, за оптимизовање и портабилност. Као такви, они су примери транскомпилатора. Ајфелов Компилатор текомп може извршити Ајфелов код директно (као интерпретатор) без одлазка преко средњег С кода који ће бити прослеђен до С компилатора да би се одржао оптимизовани матерњи код. На .NET, АјфелСтудио компилатор директно генерише CIL(Чести средњи језик)код. Паметни Ајфел компилатор такође може избацити Јавин бајткод.

Референце[уреди]

  1. Cooper, Peter (2009). Beginning Ruby: From Novice to Professional. Beginning from Novice to Professional (2nd изд.). Berkeley: APress. стр. 101. ISBN 1-4302-2363-4. »To a lesser extent, Python, LISP, Eiffel, Ada, and C++ have also influenced Ruby.« 
  2. Formal Specification Languages: Eiffel, Denotational Semantics, Vienna Development Method, Abstract Machine Notation, Petri Net, General Books, 2010
  3. Object-Oriented Software Construction, Second Edition, by Bertrand Meyer, Prentice Hall. 1997. ISBN 0-13-629155-4.
  4. ECMA International: Standard ECMA-367 —Eiffel: Analysis, Design and Programming Language 2nd edition (June 2006); available online at www.ecma-international.org/publications/standards/Ecma-367.htm
  5. International Organisation for Standardisation: Standard ISO/IEC DIS 25436, available online at [1]
  6. Bertrand Meyer: Overloading vs Object Technology, in Journal of Object-Oriented Programming (JOOP), vol. 14, no. 4, October–November 2001, available online
  7. "9 INHERITANCE".
  8. "Multiple Inheritance and Interfaces".
  9. "Multiple Inheritance Is Not Evil".
  10. Computer insurance  Kernel (computing) .
  11. Philippe Ribet, Cyril Adrian, Olivier Zendra, Dominique Colnet: Conformance of agents in the Eiffel language, in Journal of Object Technology, vol. 3, no. 4, April 2004, Special issue: TOOLS USA (2003). стр. 125-143.
  12. Brooke, Phillip; Richard Paige (2008).
  13. Brooke, Phillip; Richard Paige (2007).

Литература[уреди]

  • Cooper, Peter (2009). Beginning Ruby: From Novice to Professional. Beginning from Novice to Professional (2nd изд.). Berkeley: APress. стр. 101. ISBN 1-4302-2363-4. »To a lesser extent, Python, LISP, Eiffel, Ada, and C++ have also influenced Ruby.« 

Спољашње везе[уреди]