Что нового

Вызов функции по ссылке из Map

ArvenPK

Новичок
Сообщения
14
Репутация
1
Здравствуйте. Вопрос к знающим, почему не работает вот такая конструкция? Не доделано в бете и стоит ждать в следующих версиях, или есть какая-то причина, почему оно не может быть реализовано?

Версия AutoIt: 3.3.13.19 (Beta)
Код:
Func f()
	ConsoleWrite("ok" & @CRLF)
EndFunc

Local $m[]
$m.f = f

$m["f"]() ; ok
$m.f() ; error
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
Код:
Local $m[]
$m.f = 'f()'
Execute($m.f)

Func f()
	For $i = 0 To 10
		ConsoleWrite($i & @LF)
	Next
EndFunc   ;==>f
 
Автор
ArvenPK

ArvenPK

Новичок
Сообщения
14
Репутация
1
Это понятно, что тут есть варианты. Кстати, зачем использовать Execute(), если можно использовать скобочную нотацию вместо точечной?
Код:
Func f(ByRef $arg)
	If Not IsArray($arg) Then Return
	For $i = 0 To UBound($arg) - 1
		$arg[$i] *= 2
	Next
EndFunc

Local $arr[] = [1, 2, 3, 4, 5]
Local $m[]
$m.f = f
$m["f"]($arr) ; [2, 4, 6, 8, 10]


Но вопрос не в том, как это обойти. Вопрос - почему оно не работает? Потому что не доделали, или есть какие-то ограничения? Если есть, то про них и хотелось бы узнать.
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
ArvenPK [?]
Кстати, зачем использовать Execute()
что значит "зачем"?
ты получаешь строку(выражение), как ты думаешь ее запустить?и не важно что ты используешь - скобки или точку, как обращение к имени

Код:
Local $int = 10
Local $m[]
$m.f = 'f($int)'
Execute($m.f)

Func f($param)
    For $i = $param To 20
        ConsoleWrite($i & @LF)
    Next
EndFunc

;или
ConsoleWrite('_______________________________________________________'&@LF)
Local $m[]
$m.f1 = 'f1(10)'
Execute($m.f1)

Func f1($param)
    For $i = $param To 20
        ConsoleWrite($i & @LF)
    Next
EndFunc

;или
ConsoleWrite('_______________________________________________________'&@LF)
Local $int = 15
Local $m[]
$m[f2] = 'f2'
Execute($m[f2($int)])

Func f2($param)
    For $i = $param To 20
        ConsoleWrite($i & @LF)
    Next
EndFunc

это все задумано для обращения к элементу по имени, чтобы не перебирать массив. а если ты хочешь помещать туда имена функций и запускать вызвав по имени, то это уже твое дело


Добавлено:
Сообщение автоматически объединено:

Код:
;или
ConsoleWrite('_______________________________________________________'&@LF)
Local $m[]
$m['param'] = '10'
f3($m['param'])

Func f3($param)
    For $i = $param To 20
        ConsoleWrite($i & @LF)
    Next
EndFunc
 
Автор
ArvenPK

ArvenPK

Новичок
Сообщения
14
Репутация
1
joiner сказал(а):
это все задумано для обращения к элементу по имени, чтобы не перебирать массив. а если ты хочешь помещать туда имена функций и запускать вызвав по имени, то это уже твое дело
С помещением имен функций как раз всё нормально.
Код:
Func f()
	ConsoleWrite("ok" & @CRLF)
EndFunc

Local $m[]
$m.f = 'f()'

Execute($m.f) ; ok
Execute($m["f"]) ; ok

$m.f1 = 'f'

Execute($m.f1 & '()') ; ok
Execute($m["f1"] & '()') ; ok

Я помещаю туда не имя функции, а указатель на функцию. Не находите, что код ниже, работает немного по разному?
Код:
Local $cw1 = 'ConsoleWrite("qweqwe" & @CRLF)'
Execute($cw1)

Local $cw2 = ConsoleWrite
$cw2("qweqwe" & @CRLF)


Вы мне твердите, что нет разницы как вызывать:
Код:
ConsoleWrite("qweqwe" & @CRLF)    ; так
Execute($cw1)                     ; или так
$cw2("qweqwe" & @CRLF)            ; или так
Execute('$cw2("qweqwe" & @CRLF)') ; или так

Это абсолютно верно, я с вами согласен.

Мой же вопрос заключается в том, почему работая с одним и тем же элементом, но обращаясь к нему разными способами, я получаю разный результат?
Код:
Func f()
	ConsoleWrite("ok" & @CRLF)
EndFunc

Local $m[]
$m.f = f

ConsoleWrite((VarGetType($m.f) = VarGetType($m["f"])) & @CRLF) ; True
ConsoleWrite(($m.f = $m["f"]) & @CRLF) ; True

$m["f"]() ; ok
$m.f() ; error



joiner сказал(а):
ты получаешь строку(выражение), как ты думаешь ее запустить?и не важно что ты используешь - скобки или точку, как обращение к имени
В случае строки(выражения) не важно, а в случае с указателем функции оказывается важно. Вот я и хочу понять баг это или фича.
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
ArvenPK [?]
Здравствуйте. Вопрос к знающим, почему не работает вот такая конструкция?
Потому что парсер несовершенный. Разработчики предлагают такой вариант со скобками:
Код:
($m.f)()

Но это уже не поддерживает AU3Check, поэтому будет работать только если его отключить #AutoIt3Wrapper_Run_AU3Check=n
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
ArvenPK
вопрос не по теме(почти), случайно, не интерпретатор пишешь?
 
Верх