Получение ошибки VEVI: переменная неправильно установлена ​​в Eiffel

Я пытаюсь создать итератор для linked_list в Eiffel.

Я получаю сообщение об ошибке: переменная задана неправильно.

Class: ITERATOR_ON_COLLECTION [E]
Feature: make
Attribute(s): {ITERATOR}.target
Line: 30

Я знаю, что это из-за безопасности пустоты, но я не знаю, как это исправить. (Я установил для безопасности void значение True и изменил предварительно скомпилированную библиотеку на безопасную версию и скомпилировал ее.)

следующий класс:

class
    ITERATOR_ON_COLLECTION [E]

inherit
    ITERATOR [E]

create
    make

feature {NONE} -- Attributes

    collection: LINKED_LIST[E]
    item_index: INTEGER

feature -- initialization

    make(c: LINKED_LIST [E])
        require
            --c /= void
        do
            --  create {COLLECTION} collection.make
            --  create collection.make -- it doesnt work with/without this line 
            collection := c
            item_index := 1
        end

    start
        do
            item_index := 1
        end

    item: STRING
        do
            Result := "hello"
        end

    next
        do
            item_index := item_index + 1
        end

    is_off: BOOLEAN
        do
            Result := True
        end


    do_until (action: PROCEDURE [E]; test: FUNCTION [E, BOOLEAN])
            -- Apply `action' to every item of `target' up to
            -- and including first one satisfying `test'.
            -- (Apply to full list if no item satisfies `test').
        require else
            action_exists: action /= Void
            test_exists: test /= Void
        do
        end

    do_while (action: PROCEDURE [E]; test: FUNCTION [E, BOOLEAN])
            -- Apply `action' to every item of `target' up to
            -- and including first one not satisfying `test'.
            -- (Apply to full list if all items satisfy `test').
        require else
            action_exists: action /= Void
            test_exists: test /= Void
        do
        end

    until_do (action: PROCEDURE [E]; test: FUNCTION [E, BOOLEAN])
            -- Apply `action' to every item of `target' up to
            -- but excluding first one satisfying `test'.
            -- (Apply to full list if no items satisfy `test'.)
        require else
            action_exists: action /= Void
            test_exists: test /= Void
        do
        end

    while_do (action: PROCEDURE [E]; test: FUNCTION [E, BOOLEAN])
            -- Apply `action' to every item of `target' up to
            -- but excluding first one satisfying not `test'.
            -- (Apply to full list if all items satisfy `test'.)
        require else
            action_exists: action /= Void
            test_exists: test /= Void
        do
        end

    there_exists (test: FUNCTION [E, BOOLEAN]): BOOLEAN
            -- Is `test' true for at least one item of `target'?
        require else
            test_exists: test /= Void
        do
        end

    for_all (test: FUNCTION [E, BOOLEAN]): BOOLEAN
            -- Is `test' true for all items of `target'?
        require else
            test_exists: test /= Void
        do
        end

end

person Hosein Zarifi    schedule 13.07.2016    source источник


Ответы (1)


Не глядя на класс ITERATOR, трудно сказать, в чем истинная причина. Вот мое предположение, что происходит:

Класс ITERATOR объявляет атрибут target прикрепленного типа. Атрибут должен быть установлен в вашей процедуре создания. Скорее всего, вам нужно отказаться от атрибута collection в вашем классе и использовать вместо него target. В зависимости от типа атрибута вам может потребоваться переопределить его в своем классе или нет.

С точки зрения усилий лучше начинать с пусто-безопасных версий классов с самого начала, и когда вы переключаетесь с не-пусто-безопасных настроек на пусто-безопасные, вам может потребоваться убедиться, что типы классов прикреплены по умолчанию (ищите параметр конфигурации "Прикреплены ли типы по умолчанию?" в диалоговом окне настройки проектов). Для этого параметра должно быть установлено значение True (это не делается автоматически в EiffelStudio до версии 16.11).

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

  • Если присоединен тип аргумента, в форме arg /= Void точки проверки нет.

  • Если предварительное условие foo указано для функции в родительском классе, нет необходимости повторять его, как

    require else
        foo
    

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

  • Если комментарии переопределенных признаков не изменились, их можно заменить на

    -- <Precursor>
    

    Таким образом, любые изменения в родительских версиях будут автоматически отражены в переобъявлениях (еще раз взгляните на плоскую форму).

person Alexander Kogtenkov    schedule 13.07.2016