Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Однократные функции, закрепление и универсальность

Параметры

Однократные процедуры

 

 

Функция close должна вызываться только один раз. Контроль над количеством ее вызовов рекомендуется возложить на глобальную переменную приложения.

Из руководства к коммерческой библиотеке функций языка C

 

Механизм однократных функций интересен и при работе с процедурами. Однократные процедуры могут применяться для инициализации общесистемного свойства, когда заранее неизвестно, какому компоненту это свойство понадобится первому.

Примером может стать графическая библиотека, в которой любая функция, вызываемая первой, должна предварительно провести настройку, учитывающую параметры дисплея. Автор библиотеки мог, конечно, потребовать, чтобы каждый клиент начинал работу с библиотекой с вызова функции настройки. Этот нюанс, в сущности, не решает проблему - чтобы справиться с ошибками, любая функция должна обнаруживать, не запущена ли она без настройки. Но если функции такие "умные", то зачем что-то требовать от клиента, когда можно нужную функцию настройки вызывать самостоятельно.

Однократные процедуры решают эту проблему лучше:

 

check_setup is

-- Настроить терминал, если это еще не сделано.

once

terminal_setup -- Фактические действия по настройке.

end

 

 

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

Однократная процедура - это важный прием, упрощающий применение библиотек и других программных пакетов.

 

 

Однократные процедуры и функции могут иметь параметры, необходимые, по определению, лишь при первом вызове.

 

 

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

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

Начнем с универсальности. Пусть в родовом классе EXAMPLE [G] есть однократная функция, чей тип родовой параметр:

 

f: G is once... end

 

 

Рассмотрим пример ее использования:

 

character_example: EXAMPLE [CHARACTER]

...

print (character_example.f)

 

 

Пока все в порядке. Но если попытаться получить константу с другим родовым параметром:

 

integer_example: EXAMPLE [INTEGER]

...

print (integer_example.f + 1)

 

 

В последней инструкции мы складываем два числа. Первое значение, результат вызова f, к сожалению, уже найдено, поскольку f - однократная функция, причем символьного, а не числового типа. Сложение окажется недопустимым.

Проблема заключается в попытке разделения значения разными формами родового порождения, ожидающими значения, тип которого определяется родовым параметром. Аналогичная ситуация возникает и с закреплением типов. Представим себе класс B, добавляющий еще один атрибут к компонентам своего родителя A:

 

class B inherit A feature

attribute_of_B: INTEGER

end

 

 

Пусть A имеет однократную функцию f, возвращающую результат закрепленного типа:

 

f: like Current is once create Result make end

 

 

и пусть первый вызов функции f имеет вид:

 

a2:= a1.f

 

 

где a1 и a2 имеют тип A. Вычисление f создаст экземпляр A и присоединит его к сущности a2. Все прекрасно. Но предположим, далее следует:

 

b2:= b1.f

 

 

где b1 и b2 имеют тип B. Не будь f однократной функцией, никакой проблемы бы не возникло. Вызов f породил бы экземпляр класса B и вернул его в качестве результата. Но функция является однократной, а ее результат был уже найден при первом вызове. И это - экземпляр A, но не B. Поэтому инструкция вида:

 

print (b2.attribute_of_B)

 

 

попытается обратиться к несуществующему полю объекта A.

Проблема в том, что закрепление вызывает неявное переопределение типов. Если бы f была переопределена явно, с применением в классе B объявления

 

f: B is once create Resultl make end

 

 

при условии, что исходный вариант f в классе A возвращает результат типа A (а не like Current), все было бы замечательно: экземпляры A обращались бы к версии f для A, экземпляры B - к версии f для B. Однако закрепление типов было введено как раз для того, чтобы избавить нас от таких явных переопределений.

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

<== предыдущая лекция | следующая лекция ==>
Однократные функции с результатами базовых типов | Unique-значения
Поделиться с друзьями:


Дата добавления: 2014-01-07; Просмотров: 324; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.012 сек.