diff --git a/README.md b/README.md index 9e16075..3d537b1 100644 --- a/README.md +++ b/README.md @@ -14,8 +14,9 @@ | `count()` | Возвращает количество элементов в стеке | | `empty()` | Возвращает `Истина`, если стек не содержит элементов | | `clear()` | Удаляет все элементы из стека | +| `contains(значение)` | Возвращает `Истина`, если указанное значение присутствует среди элементов стека | -Стек может хранить значения любого типа, включая объекты — `pop()`/`peek()` возвращают тот же самый объект, который был передан в `push()`, без копирования. +Стек может хранить значения любого типа, включая объекты — `pop()`/`peek()` возвращают тот же самый объект, который был передан в `push()`, без копирования. `contains()` сравнивает значения строгим равенством: для примитивов (числа, строки и т.п.) — по значению, для объектов — по ссылке. ## Установка @@ -47,6 +48,11 @@ Стек.push(1); Стек.clear(); Сообщить(Стек.empty()); // Истина + +Стек.push(1); +Стек.push(2); +Сообщить(Стек.contains(2)); // Истина +Сообщить(Стек.contains(35)); // Ложь ``` Попытка получить элемент из пустого стека (`pop()` или `peek()`) бросает исключение с текстом `stack underflow`: diff --git a/src/stack.os b/src/stack.os index e8772de..dba86e5 100644 --- a/src/stack.os +++ b/src/stack.os @@ -1,79 +1,117 @@ - -Var mStackContainer; - -// Возвращает количество элементов, находящихся в стеке. -// -// Возвращаемое значение: -// Число - количество элементов в стеке. -// -Function count() Export - return mStackContainer.count(); -EndFunction - -// Добавляет элемент на вершину стека. -// -// Параметры: -// value - Произвольный - значение, добавляемое на вершину стека. -// -Function push(value) Export - mStackContainer.add(value); -EndFunction - -// Извлекает элемент с вершины стека и удаляет его из стека. -// Если стек пуст, вызывает исключение с текстом "stack underflow". -// -// Возвращаемое значение: -// Произвольный - значение, находившееся на вершине стека. -// -Function pop() Export - Var topValue; - - // we want to check for underflow and throw exception here - // peek() does this so we utilize it to reuse code - topValue = this().peek(); - mStackContainer.delete(mStackContainer.UBound()); - - return topValue; -EndFunction - -// Возвращает элемент с вершины стека, не удаляя его из стека. -// Если стек пуст, вызывает исключение с текстом "stack underflow". -// -// Возвращаемое значение: -// Произвольный - значение, находящееся на вершине стека. -// -Function peek() Export - If this().empty() Then - Raise "stack underflow: attempt to get element out of empty stack object"; - Endif; - - return mStackContainer.get(mStackContainer.UBound()); -EndFunction - -// Проверяет, пуст ли стек. -// -// Возвращаемое значение: -// Булево - Истина, если стек не содержит элементов; иначе Ложь. -// -Function empty() Export - Return 0 = this().count(); -EndFunction - -// Удаляет все элементы из стека. -// -Procedure clear() Export - mStackContainer.Clear(); -EndProcedure - -Function this() - // early versions of intepreter didn't have ThisObject variable, - // only it's russian synonym - ЭтотОбъект - return ЭтотОбъект; -EndFunction - -Procedure init() - mStackContainer = New Array; -EndProcedure - - -init(); \ No newline at end of file + +Var _StackContainer; + +// Возвращает количество элементов, находящихся в стеке. +// +// Возвращаемое значение: +// Число - количество элементов в стеке. +// +Function count() Export + + return _StackContainer.count(); + +EndFunction + + +// Добавляет элемент на вершину стека. +// +// Параметры: +// value - Произвольный - значение, добавляемое на вершину стека. +// +Function push( value ) Export + + _StackContainer.add( value ); + +EndFunction + + +// Извлекает элемент с вершины стека и удаляет его из стека. +// Если стек пуст, вызывает исключение с текстом "stack underflow". +// +// Возвращаемое значение: +// Произвольный - значение, находившееся на вершине стека. +// +Function pop() Export + + Var topValue; + + // we want to check for underflow and throw exception here + // peek() does this so we utilize it to reuse code + topValue = this().peek(); + _StackContainer.delete( _StackContainer.UBound() ); + + return topValue; + +EndFunction + + +// Возвращает элемент с вершины стека, не удаляя его из стека. +// Если стек пуст, вызывает исключение с текстом "stack underflow". +// +// Возвращаемое значение: +// Произвольный - значение, находящееся на вершине стека. +// +Function peek() Export + + If this().empty() Then + Raise "stack underflow: attempt to get element out of empty stack object"; + Endif; + + return _StackContainer.get( _StackContainer.UBound() ); + +EndFunction + + +// Проверяет, пуст ли стек. +// +// Возвращаемое значение: +// Булево - Истина, если стек не содержит элементов; иначе Ложь. +// +Function empty() Export + + Return 0 = this().count(); + +EndFunction + + +// Проверяет наличие указанного значения среди элементов стека. +// +// Параметры: +// value - Произвольный - значение, наличие которого проверяется. +// +// Возвращаемое значение: +// Булево - Истина, если значение содержится в стеке; иначе Ложь. +// +Function contains( value ) Export + + Return _StackContainer.Find( value ) <> Undefined; + +EndFunction + + +// Удаляет все элементы из стека. +// +Procedure clear() Export + + _StackContainer.Clear(); + +EndProcedure + + +Function this() + + // early versions of intepreter didn't have ThisObject variable, + // only it's russian synonym - ЭтотОбъект + return ЭтотОбъект; + +EndFunction + + +Procedure init() + + _StackContainer = New Array; + +EndProcedure + + +init(); diff --git a/tests/stack.os b/tests/stack.os index 8e4c9e0..5c53838 100644 --- a/tests/stack.os +++ b/tests/stack.os @@ -34,6 +34,12 @@ Тесты.Добавить("ВызовClearОпустошаетСтек"); Тесты.Добавить("ВызовClearУЖеПустогоСтекаНеГенерируетИсключение"); + Тесты.Добавить("ДолженИметьМетодContains"); + Тесты.Добавить("МетодContainsВозвращаетИстинаЕслиЗначениеЕстьВСтеке"); + Тесты.Добавить("МетодContainsВозвращаетЛожьЕслиЗначенияНетВСтеке"); + Тесты.Добавить("МетодContainsВозвращаетЛожьДляПустогоСтека"); + Тесты.Добавить("МетодContainsНеИзменяетКоличествоЭлементов"); + Возврат Тесты; КонецФункции @@ -424,6 +430,76 @@ ОсвободитьОбъект(Стек); КонецПроцедуры +Функция ДолженИметьМетодContains() Экспорт + Перем Стек, Рефлектор; + + Стек = Новый Стек; + Рефлектор = Новый Рефлектор; + Ожидаем + .Что(Рефлектор.МетодСуществует(Стек, "contains"), "Объект стека должен иметь метод contains()") + .ЭтоИстина() + ; + + ОсвободитьОбъект(Стек); + ОсвободитьОбъект(Рефлектор); +КонецФункции + +Функция МетодContainsВозвращаетИстинаЕслиЗначениеЕстьВСтеке() Экспорт + Перем Стек; + + Стек = Новый Стек; + Стек.push(1); + Стек.push(2); + Стек.push(3); + Ожидаем + .Что(Стек.contains(2), "Значение, добавленное в стек, должно быть найдено методом contains()") + .Равно(Истина) + ; + + ОсвободитьОбъект(Стек); +КонецФункции + +Функция МетодContainsВозвращаетЛожьЕслиЗначенияНетВСтеке() Экспорт + Перем Стек; + + Стек = Новый Стек; + Стек.push(1); + Стек.push(2); + Ожидаем + .Что(Стек.contains(35), "Значение, не добавлявшееся в стек, не должно быть найдено методом contains()") + .Равно(Ложь) + ; + + ОсвободитьОбъект(Стек); +КонецФункции + +Функция МетодContainsВозвращаетЛожьДляПустогоСтека() Экспорт + Перем Стек; + + Стек = Новый Стек; + Ожидаем + .Что(Стек.contains(1), "У пустого стека не может быть найдено ни одно значение") + .Равно(Ложь) + ; + + ОсвободитьОбъект(Стек); +КонецФункции + +Функция МетодContainsНеИзменяетКоличествоЭлементов() Экспорт + Перем Стек; + + Стек = Новый Стек; + Стек.push(1); + Стек.contains(1); + Стек.contains(35); + Ожидаем + .Что(Стек.count(), "Вызов contains() не должен изменять количество элементов в стеке") + .Равно(1) + ; + + ОсвободитьОбъект(Стек); +КонецФункции + Процедура Инициализация() ПодключитьСценарий(ОбъединитьПути(ТекущийСценарий().Каталог, "..", "src", "stack.os"), "Стек"); КонецПроцедуры