Что нового

[Баг] Assign создаёт не валидные переменные

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,659
Репутация
2,457
Как выяснилось, Assign может создать переменную которая является “неправильной” переменной, т.е может содержать практический любые символы, включая пробелы!

А Eval в свою очередь умеет распознавать такие переменные.

Код:
Assign("Переменная", "Значение")
MsgBox(64, 'Title', "$Переменная=" & Eval("Переменная"))


однако использовать такую переменную традиционно нельзя:
Код:
$Переменная ;Естественно выдаёт ошибку


Не знаю баг ли это, но это явно непредвиденное поведение, хотя и весьма полезное.
 

SyDr

Сидра
Сообщения
651
Репутация
158
Возможно, что поведение аналогично поведению с Default - не обрабатывается, чтобы ускорить обработку скрипта.
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,716
А вы создайте тикет, может разработчики исправят это дело, и скорость вернется в привычное русло.

:smile:
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
964
IMHO это не баг, потому как именно Assign и Eval тут как нельзя, кстати, показывают нам, что в Autoit`e можно использовать имена переменных какие вам вздумается. CreatoR кстати это очень наглядный пример к нашему разговору о правильности обращения к переменным! Именно для таких ("своих") переменных видимо и нужны эти функции.
Вот примеры, которые показывают работу Assign и Eval:

Код:
Assign("a.b", 12)
Assign("a+b", 12)
Assign("a_b", 12)
Assign("ab", 12)

ConsoleWrite(Eval("a" & "_" & "b") & @CRLF)
ConsoleWrite($a_b & @CRLF)
ConsoleWrite(Eval("a" & "+" & "b") & @CRLF) ; тут как раз таки и нужна функция Eval
;~ ConsoleWrite($a+b & @CRLF) ; тут будет ошибка. плюс зарезервированный оператор
ConsoleWrite(Eval("a" & "." & "b") & @CRLF) ;  тут как раз таки и нужна функция Eval
;~ ConsoleWrite($a.b & @CRLF) ; тут будет ошибка. точка зарезервированна для работы с объектами
ConsoleWrite(Eval("ab") & @CRLF)
ConsoleWrite($ab & @CRLF)
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
964
SyDr сказал(а):
Справка AutoIt сказал(а):
Each variable has a name and must start with the $ character and may only contain letters, numbers and the underscore _ character.
Ну тогда ничего не поделаешь! ;D

P.S. IMHO Eval в других случаях бесполезная функция в Autoit.

Кстати, кто сможет внятно прокомментировать этот код:
Код:
Dim $ab
Assign("ab", 12, 4) ; смысл этой записи?
ConsoleWrite(Eval("ab")) ; смысл этой записи?
ConsoleWrite($ab)
;~ гораздо рациональнее придерживаться правил!
;~ 1. любая переменная должна быть объявлена, прежде чем она будет использоваться
;~ 2. объявлять пространство действия этой переменной
;~ Assign полезная функция, а вот Eval IMHO бесполезная
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,716

SyDr

Сидра
Сообщения
651
Репутация
158
Смсысл использования Eval() состоит в том, что вы можете спокойно обращаться к несуществующим переменным.

Код:
Dim $vTemp
While Not @error
	$vTemp = InputBox("Введите число от 1 до 100", "Введите число от 1 до 100", $vTemp)
	If Not @error And $vTemp > 0 And $vTemp < 101 Then Assign('a' & $vTemp, Eval('a' & $vTemp) + 1)
WEnd

$vTemp &= 'Вы ввели следующие числа:' & @CRLF

For $iCount = 1 To 100
	If IsDeclared('a' & $iCount) Then $vTemp &= 'Число ' & $iCount & ' введено ' & Eval('a' & $iCount) & ' раз' & @CRLF
Next

MsgBox(262144, Default, $vTemp)
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,659
Репутация
2,457
Garrett [?]
скорее полезная!
А я что написал? :blink:

[?]
Assign и Eval тут как нельзя, кстати, показывают нам, что в Autoit`e можно использовать имена переменных какие вам вздумается.
Кто показывает? в справке об этом ни слова. Единственное ограничение которое упоминаетя, это использование элементов массива:

Код:
$sVarName = "Переменная[0]"
Assign($sVarName, "Значение")
MsgBox(64, 'Title', "$" & $sVarName & "=" & Eval($sVarName))


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

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
622
OffTopic:
CreatoR [?]
чтобы добавили упоминание данного поведения в справку
как бы не убрали эту фичу из проекта, вместо этого ;D
 

amel27

Продвинутый
Сообщения
146
Репутация
55
Garrett
;~ гораздо рациональнее придерживаться правил!
;~ 1. любая переменная должна быть объявлена, прежде чем она будет использоваться
;~ 2. объявлять пространство действия этой переменной
;~ Assign полезная функция, а вот Eval IMHO бесполезная
следуя такой логике, следовало бы просить разработчиков сделать обязательным объявление всех переменных... ;)

я не вижу тут бага, просто у Assign/Eval больше возможностей распознать имя переменной, чем у интерпретатора, которому приходится его вычленять из потока кода... ограничение ввести можно, но оно будет заведомо искусственным

P.S. кстати, с точки зрения идеологии процедурного программирования Assign/Eval как раз и есть наиболее правильный (базовый) метод работы с переменными... другое дело, что этой парочке не хватает Enum(), возвращающей массив задействованных имен переменных, желательно с фильтром по имени (в идеале - regexp)
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,659
Репутация
2,457
amel27 [?]
другое дело, что этой парочке не хватает Enum(), возвращающей массив задействованных имен переменных, желательно с фильтром по имени (в идеале - regexp)
Отличная идея, нужно бы разработчикам подкинуть.
 

SyDr

Сидра
Сообщения
651
Репутация
158
Enum в AutoIt есть. Только он другое делает :smile:
 
Верх