API Basic With - LIHACHTETAN/ClassicUO-BadNewbie-BasicIDE GitHub Wiki

With / End With

ClassicUO • Basic

With объединяет операции над одним сохранённым объектом. Точка перед именем выбирает его метод. В Basic также есть With UO и With moduleName — явное указание пространства имён; эти две формы являются расширениями движка.

Точный синтаксис

With objectExpression
    .Method(arguments)
    statements
End With
With UO
    .Command(arguments)
End With
With moduleName
    .field = expression
    .Procedure(arguments)
End With

Параметры

  • objectExpression / UO / moduleName — Обязательный получатель: объект List(), Dictionary(), переменная с таким объектом либо функция, возвращающая объект. Выражение вычисляется один раз при входе, даже для пустого тела. Числа, строки, массивы и Unit здесь не подходят. Локальная переменная с объектом имеет приоритет над одноимённым модулем.
  • .Method(arguments) / .field — У объектов вызывайте методы со скобками: .Add(value), .Item(index), .Count(). Параметры и результаты сохраняют обычный смысл: см. Basic.List/Basic.Dictionary. Произвольные поля и свойства объектов здесь не поддерживаются. У модуля доступны .field и .Procedure(arguments) с соблюдением Private. В With UO запись .Command(...) означает UO.Command(...); вне блока игровые команды по-прежнему требуют UO.
  • statements / End With — Тело может быть пустым или содержать вызовы, присваивания, условия и правильно вложенные циклы/блоки. End With обязателен. Обращение с начальной точкой вне тела — ошибка. К другим объектам можно обращаться по полному имени.

Возвращает

With — управляющий блок, а не функция: он не возвращает ID, Boolean или признак успеха. Каждый вызванный метод сохраняет собственный результат. Return в примерах явно возвращает Integer из Main; 127, 28 и 72 — расчёты примеров.

Поведение

  • При подготовке движок проверяет блок и связывает относительные имена. При входе интерпретатор вычисляет выражение и сохраняет ссылку на объект в области текущего вызова. Присваивание исходной переменной другого объекта эту ссылку не меняет. Повторный вход через заголовок вычисляет выражение заново; рекурсивные вызовы имеют отдельные ссылки.
  • Заголовок вложенного With вычисляется в контексте внешнего блока; в его теле точка относится уже к внутреннему объекту. End With восстанавливает внешний контекст. Return, переходы цикла и GoTo наружу освобождают покидаемые области после соответствующих Finally. Переход внутрь тела With запрещён.
  • Неподходящий получатель или неизвестный метод вызывает ошибку, а не false. Её может обработать Catch/On Error. Если ошибка возникла при вычислении получателя, On Error Resume Next пропускает весь блок. With сам не повторяет действия, не ждёт и не создаёт поток. Проверки паузы/остановки сохраняются. Связанные имена кэшируются с подготовленным скриптом; получатель не вычисляется заново при каждом вызове метода.

Примеры

1. Одно вычисление получателя

# Choose получает values через ByVal, а calls через ByRef; увеличивает calls до 1 и возвращает исходный список. Оба .Add добавляют в сохранённый список значения 2 и 7, хотя между ними переменной values присвоен новый список. Item использует индексы 0 и 1. Main возвращает 1*100+2*10+7=127.
Option Explicit On
Function Choose(ByVal values, ByRef calls) As Object
    calls += 1
    Return values
End Function

Sub Main()
    Dim calls=0
    Dim values=List()
    Dim original=values
    With Choose(values, calls)
        .Add(2)
        values=List()
        .Add(7)
    End With
    Return calls*100+original.Item(0)*10+original.Item(1)
End Sub

Разбор параметров и выполнения:

Choose получает values через ByVal, а calls через ByRef; увеличивает calls до 1 и возвращает исходный список. Оба .Add добавляют в сохранённый список значения 2 и 7, хотя между ними переменной values присвоен новый список. Item использует индексы 0 и 1. Main возвращает 1100+210+7=127.

2. Вложенные объекты и завершение

# groups хранит список child под строковым ключом "child". .Item("child") получает объект через внешний словарь. Внутренние .Add(2) и .Add(7) в Finally меняют список. После End With запись .Set("result",8) снова обращается к словарю. Count() возвращает два элемента, Item("result") — 8, поэтому Main возвращает 28.
Option Explicit On
Sub Main()
    Dim groups=Dictionary()
    Dim child=List()
    groups.Set("child", child)
    With groups
        With .Item("child")
            Try
                .Add(2)
            Finally
                .Add(7)
            End Try
        End With
        .Set("result", 8)
    End With
    Return child.Count()*10+groups.Item("result")
End Sub

Разбор параметров и выполнения:

groups хранит список child под строковым ключом "child". .Item("child") получает объект через внешний словарь. Внутренние .Add(2) и .Add(7) в Finally меняют список. После End With запись .Set("result",8) снова обращается к словарю. Count() возвращает два элемента, Item("result") — 8, поэтому Main возвращает 28.

3. Поля модуля и пространство UO

# With Tools уточняет имена .total, .AddAmount и .CountItems. total получает 4, а AddAmount получает amount=3 через ByVal: получается 7. CountItems принимает массив из двух элементов и через With UO вызывает UO.GetArrayLength(values), получая 2. Main вычисляет 7*10+2=72. Правила доступа модуля сохраняются.
Option Explicit On
Module Tools
    Public Var total=0
    Public Sub AddAmount(ByVal amount)
        total += amount
    End Sub
    Public Function CountItems(ByVal values) As Integer
        With UO
            Return .GetArrayLength(values)
        End With
    End Function
End Module

Sub Main()
    Dim values[1]
    With Tools
        .total=4
        .AddAmount(3)
        Return .total*10+.CountItems(values)
    End With
End Sub

Разбор параметров и выполнения:

With Tools уточняет имена .total, .AddAmount и .CountItems. total получает 4, а AddAmount получает amount=3 через ByVal: получается 7. CountItems принимает массив из двух элементов и через With UO вызывает UO.GetArrayLength(values), получая 2. Main вычисляет 7*10+2=72. Правила доступа модуля сохраняются.


en · ru · uk · fr · de · it · es · zh-tw · ja · ko

Basic