Странность с пропущенными параметрами.

Автор ost, 3 августа 2021, 16:10

0 Пользователи и 1 гость просматривают эту тему.

mikekaganski

С уважением,
Михаил Каганский

eeigor

Ещё раз перечитал ветку по ссылке в ответе #2.
Вопрос за вопросом на примере использования логической переменной.
И вот совет:
«Try to use two variables to handle the optional parameter».

О чём я и писал выше: двойной комплект переменных. Пытаюсь уйти от этого...
Ubuntu 18.04 LTS • LibreOffice 7.5.1.2 Community

mikekaganski

И причём тут тот бессмысленный совет?
С уважением,
Михаил Каганский

eeigor

#18
А при том, что это и есть абсолютно работающий во всех режимах единственный (простой) вариант использования опциональных переменных в StarBasic – одна переменная для переданного параметра (сам параметр процедуры), а другая для использования в теле после анализа входного параметра*. По другому не так просто, со всеми особенностями. Во всяком случае совет дан старожилом форума.

А.Питоньяк тоже использует этот приём: passed – inner

Что и как для трёх режимов и отдельно на листе (UDF) нигде не описано: собираем по крохам.

Upd
* После анализа входного параметра (Variant) мы наконец-то можем присвоить значение внутренней переменной конкретизированного типа данных. Потому что "Optional bVariable As Boolean" – совсем не то, что вы можете ожидать и с чем можете столкнуться (по моей ссылке выше на англоязычный форум всё начинается с разбора этой ситуации).
Ubuntu 18.04 LTS • LibreOffice 7.5.1.2 Community

mikekaganski

Как этот метод отличается по результату от

Sub Foo(Optional Bar As Boolean)
 If IsMissing(Bar) Then Bar = True
End Sub


в любом режиме?
С уважением,
Михаил Каганский

eeigor

#20
Ну, у меня было так, как описал:

«2. Function UDF(Optional bStatus As Boolean)
 If IsMissing(bStatus) Then: End If

And bStatus will automatically be set to False after calling the IsMissing function. Why?
 If IsMissing(bStatus) Then bStatus = True

Alas, the missing parameter after the call to the IsMissing function is set to False and is no longer considered missing and will not be assigned a new value of True. Is this a bug?»

Версии ПО разные, конечно, но исходя из того, что я описал, вторая часть условия (Then) никогда не будет выполнена, потому что обращение к отсутствующему параметру автоматически устанавливает его значение в FALSE, и TRUE уже не присвоить.
Ubuntu 18.04 LTS • LibreOffice 7.5.1.2 Community

sokol92

#21
Михаил, спасибо за описание бага.

Итак, уточним текущее состояние дел для макросов Basic.

1. В родном режиме (без Option Compatible, Option VBASupport)

  При пропуске необязательного (Optional) параметра любого типа функция IsMissing(arg) возвращает True, функция IsError(arg) возвращает True, при преобразовании параметра в строку выдается "Error 448". Естественно, дальнейшее использование такого параметра сопряжено с проблемами.
Присвоение необязательным параметрам значения по умолчанию режим не допускает.

2. Option Compatible
 
  При незадании значения по умолчанию - так же, как в предыдущем пункте. Если в шапке функции задан параметр по умолчанию, то IsMissing(arg) возвращает False (и, таким образом, нет возможности узнать, пропущен параметр при вызове функции или указан явно со значением по умолчанию).

3. Option VBASupport 1

  При пропуске необязательного параметра любого типа, кроме Variant, функция IsMissing(arg) выдает False, параметр инициализируется значением по умолчанию. Если значение по умолчанию не задано, то присваивается 0 для числовых типов, пустая строка для строк, false для логических и т.д.
  При пропуске необязательного параметра типа Variant, у которого не задано значение по умолчанию,  функция IsMissing(arg) возвращает True, функция IsError(arg) возвращает True, при преобразовании параметра в строку выдается "Error 448" (так же, как и в других режимах). Если параметр имеет значение по умолчанию, то IsMissing(arg) выдает False, параметр инициализируется значением по умолчанию.
  Поведение в этом режиме, на мой взгляд, соответствует VBA.

  Неожиданно обнаружил в этом режиме "баг" (?). Если значение параметра типа Variant по умолчанию 1 (или другое целое число), то аргумент преобразуется в строку и добавляется знак процента ("1%"). Сейчас отрапортую (tdf#143707).


  Прикладываю "стенд" для дальнейших испытаний.

Option Explicit
Option Compatible

Sub Mysub(Optional ByVal arg1 As String, Optional ByVal arg2 As Long=0)
 Dim v As Long
 Msgbox "arg1: IsMissing " & IsMissing(arg1) & " IsError=" & IsError(arg1) & " " & arg1 & Chr(10) & _
        "arg2: IsMissing " & IsMissing(arg2) & " IsError=" & IsError(arg2) & " " & arg2
 v=arg1+1      
End Sub

Sub Test
 Mysub
 ' Mysub  ,2
End Sub  
Владимир.

eeigor

Ошибка 448 «пролетает» незаметно и существенных проблем, однако, не создаёт.
Ubuntu 18.04 LTS • LibreOffice 7.5.1.2 Community

mikekaganski

Цитата: eeigor от  3 августа 2021, 18:59
Ну, у меня было так, как описал:

Так Вы не описали. Это просто набор букв. Что может значить, например, "And bStatus will automatically be set to False after calling the IsMissing function". Чему равен bStatus до вызова? Что вернёт сам вызов? Если IsMissing(bStatus) возвратит False, то неважно, будете Вы в ветви If True присваивать значение переменной bStatus или bInnerStatus - ни то, ни другое не выполнится. Если же возвращается True, то неважно, изменил вызов IsMissing значение bStatus или нет.

А может быть, тут вообще что-то другое имеется ввиду? Но это именно то, о чём пишу: ничего не описано.
С уважением,
Михаил Каганский

sokol92

Цитата: eeigor от  3 августа 2021, 19:14Ошибка 448 «пролетает» незаметно и существенных проблем, однако, не создаёт.
Добавьте к этой переменной, например, 1.
Владимир.

eeigor

#25
Михаил, во всяком случае у меня до TRUE «дело» не доходит:

Sub Foo(Optional Bar As Boolean)
 If IsMissing(Bar) Then Bar = True
End Sub

PS. Я пишу со смартфона и излагаю настолько подробно, насколько возможно. А ссылку давал на целую ветку с примерами и и.п.

Upd
Но и уже очевидно, что мой «прогноз» на необходимость исследование «этой темы» имеет под собой «основания. Всё очень непросто
Ubuntu 18.04 LTS • LibreOffice 7.5.1.2 Community

mikekaganski

Цитата: sokol92 от  3 августа 2021, 19:08При пропуске необязательного (Optional) параметра любого типа функция IsMissing(arg) возвращает True, функция IsError(arg) возвращает True, при преобразовании параметра в строку выдается "Error 448". Естественно, дальнейшее использование такого параметра сопряжено с проблемами.

Обратите внимание на важный специальный случай использования такого значения:
Sub Foo(Optional Arg)
 If IsMissing(Arg) Then MsgBox "Missing!"
  ...
End Sub

Sub Bar(Optional Arg)
 Foo(Arg)
End Sub

...
Bar


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

mikekaganski

Цитата: eeigor от  3 августа 2021, 19:23Но и уже очевидно, что мой «прогноз» на необходимость исследование «этой темы» имеет под собой «основания. Всё очень непросто

Непросто здесь только одно: отсутствие внятного описания проблемы. У меня всё работает, и должно работать. А если не работает - это баг.
С уважением,
Михаил Каганский

eeigor

#28
Ну, проблема в общем-то ясна. Вы слышите @economist'a? Правильно, нет. Потому как нет таких проблем в среде, которую он использует. Шучу.

Sub Foo(Optional Bar As Boolean)
 If IsMissing(Bar) Then Bar = True
End Sub

Ваш пример, Михаил. Однако у меня до TRUE дело не доходит.
Вторая часть условия (Then) никогда не будет выполнена, потому что обращение к отсутствующему параметру автоматически устанавливает его значение в FALSE, и TRUE уже не присвоить.

Upd. Да, в режиме совместности
Option Compatible
Ubuntu 18.04 LTS • LibreOffice 7.5.1.2 Community

sokol92

Цитата: eeigor от  3 августа 2021, 19:35Однако у меня до TRUE дело не доходит
Что не так в ответе #21?
Владимир.