Что нового

Стили программирования в AutoIt

SyDr

Сидра
Сообщения
651
Репутация
158
Хотелось бы обсудить различные стили программирования в AutoIt

http://autoit-script.ru/index.php/topic,158.0.html
Стараюсь придерживаться этих правил при придумывании имён. С той лишь разницей, что для массивов часто не прописываю "тип", а для целых и вещественных чисел использую префиксы $n и $r соответственно.
А каких ещё правил стараетесь придерживаться вы?

Впрочем, вот ещё вопрос:
Код:
#include "ZInclude.au3"

Global $sTest = "Bzzzzz..."
Global $iOptions = 16 + 4 + 1

$sTest = _ZInclude($sTest, $iOptions)
MsgBox(4096, Default, $sTest)

Код ZInclude.au3:
Код:
Func _ZInclude($sTest, $iOptions)
	Return StringTrimLeft($sTest, 5) & __Hidden($sTest, $iOptions)
EndFunc

Func __Hidden($sTest, $iOptions)
	Return $sTest & $iOptions
EndFunc


Т. е. во включённом файле есть функция, использующая переменные из основного скрипта. Как быть в такой ситуации?
1) Тянуть через все вызываемые функции в параметрах? (Как в примере)
2) Просто сразу использовать глобальную переменную?
Код ZInclude.au3 для этого случая:
Код:
Func _ZInclude($sTest, $iOptions)
	Return StringTrimLeft($sTest, 5) & __Hidden($sTest)
EndFunc

Func __Hidden($sTest)
	Return $sTest & $iOptions
EndFunc

В этом случае каждый раз при запуске будет вызываться Warning:
Код:
D:\Projects\AutoIt\Translate\3.3.6.1.RUS.NEWSYSTEM\docs\autoit\russian\Build\ZInclude.au3(6,27) : WARNING: $iOptions: possibly used before declaration.
	Return $sTest & $iOptions
	~~~~~~~~~~~~~~~~~~~~~~~~~^
D:\Projects\AutoIt\Translate\3.3.6.1.RUS.NEWSYSTEM\docs\autoit\russian\Build\ZMain.au3 - 0 error(s), 1 warning(s)
->10:43:08 AU3Check ended.rc:1
3) Писать всё в одном файле и использовать глобальные переменные
Код:
Global $sTest = "Bzzzzz..."
Global $iOptions = 16 + 4 + 1

$sTest = _ZInclude($sTest, $iOptions)
MsgBox(4096, Default, $sTest)

Func _ZInclude($sTest, $iOptions)
	Return StringTrimLeft($sTest, 5) & __Hidden($sTest)
EndFunc

Func __Hidden($sTest)
	Return $sTest & $iOptions
EndFunc

В этом случае отладка скрипта превращается в настоящий ад.

А как пишете/поступили бы вы?
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 711
В #Include обычно содержаться законченные и самодостаточные функции, и естественно никаких переменных из "родительского" файла использовать не должны. Функции из других модулей (файлов) должны общаться с программой, которая их вызывает, только посредством передаваемых/возвращаемых параметров. IMHO по аналогии с dll. Другой вопрос, если функции являются локальными по отношению к самой программе. В этом случае можно и нужно использовать глобальные переменные, если конечно это логически оправдано.
 
Автор
SyDr

SyDr

Сидра
Сообщения
651
Репутация
158
Я тут немного отдохнул и теперь переписываю свой жуткий код.
Дело в том, что в AutoIt нет возможности создвать вложенные функции.
У меня есть функция, конвертирующая специально сформированный текст в html. Эта функция принимает в параметрах сам текст, некоторые опции и некоторые строки. Сама функция использует ещё несколько функций. Однако, использовать эти переданные параметры в данных функциях я не могу - их не существует. В таком случае мне необходимо передавать параметры по цепочке или использовать глобальные переменные (и получать предупреждения, мол, указанные переменные могут не существовать) или писать всё в одном файле (а потом мучаться, из-за мелких ошибок). Впрочем, я, пожалуй, придумал выход.
 

Yashied

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

Func Main($sText)
	$__Data = $sText
	SunFunc()
	Return $__Data
EndFunc

Func SubFunc()
	$__Data = 'Хе-Хе'
	SubSubFunc()
EndFunc

Func SubSubFunc()
	$__Data &= 'Ха-Ха'
EndFunc
 

shm_alex

Новичок
Сообщения
34
Репутация
4
ИМХО:
Я насколько понимаю вопрос касается следующего
Например язык паскаль позволяет структурировать доступ к данным на уровне языка
(Да простят меня те кто помнит ещё синтаксис этого языка - я не помню, но идея мне кажется понятна)
Код:
Program X;
var
c:integer;
	procedure Klop()
	var
	integer Klop_Variable_1, Klop_Variable_2
		procedure Sub_Klop()
		var 
		integer Sub_Klop_Variable_1, Sub_Klop_Variable_2;
		begin
			Sub_Klop_Variable_1:=Random(Klop_Variable_1);
			Sub_Klop_Variable_2:=Random(Klop_Variable_1);
			Klop_Variable_2:=Sub_Klop_Variable_2-Sub_Klop_Variable_1
		end;(* procedure Sub_Klop()*)
	begin
	c:=Klop_Variable_2
	end;
begin

end
Декомпозиция сверху вниз данных, и функциональности поддерживается на уровне языка.
Например переменные Klop_Variable_1 и Klop_Variable_2 во вспомогательную функцию Sub_Klop() - передавать не нужно не по ссылке , ни через параметры, с другой стороны они локальные для процедуры Klop и доступ из основной программы к ним получить нельзя.
В AutoIt я так понимаю очевидного способа структурирования данных и функциональности сверху вниз нет (как впрочем и в языке Си - там это возможно сделать на уровне модуля)
Для тех кто учился мыслить в парадигме декомпозиции задачи очень трудно иногда отказаться от этого образа мышления, и вызывает часто раздражение обилие глобальных переменных или необходимость передавать данные в функции ниже через параметры (под параметры ведь выделяется память , определённые расходы процессорного времени идут на упаковку распаковку параметров, их копирование, в случае передачи их не-по-ссылке) и потом их нужно банально писать ручками в сигнатурах функций.
Сам плевался когда переходил с паскаля на си, теперь смотрю иронично на своё прошлое и не могу без строк типа i++;
 
Автор
SyDr

SyDr

Сидра
Сообщения
651
Репутация
158
Yashied, я переписал весь файл в одну функцию. Теперь в этой функции всего 330 строчек (а раньше было 500). Плюс, принцип работы функции стал более понятен и прозрачен.

shm_alex
Да, в том и дело, что в программе на Паскале - каждая процедура и функция сама, по сути, является "программой", т.е., может иметь свои собственные, недоступные из основной программы, функции, процедуры и типы данных.
P.S. Синтаксис жесток :smile:
P.P.S. Чем i:=i+1 или Inc(i) хуже i++?
 

Guezt

Продвинутый
Сообщения
335
Репутация
81
Стараюсь избегать подобного:
Код:
If True And Not False And True Then MsgBox(0,'', 'Это мой первый скрипт. КЭП!') 
; Если правда - это не ложь и правда тогда... ))

:rofl:
 

sendsay

sendsay
Сообщения
29
Репутация
0
SyDr сказал(а):
Yashied, я переписал весь файл в одну функцию. Теперь в этой функции всего 330 строчек (а раньше было 500). Плюс, принцип работы функции стал более понятен и прозрачен.

shm_alex
Да, в том и дело, что в программе на Паскале - каждая процедура и функция сама, по сути, является "программой", т.е., может иметь свои собственные, недоступные из основной программы, функции, процедуры и типы данных.
P.S. Синтаксис жесток :smile:
P.P.S. Чем i:=i+1 или Inc(i) хуже i++?
Inc(i) и i++, это по битовое смещение в плюс, а оно как известно работает быстрее чем i:=i+1; да и код выглядит красивее. )))
 
Автор
SyDr

SyDr

Сидра
Сообщения
651
Репутация
158
Сомневаюсь, что именно в таком виде оно будет работать быстрее. Компилятор (FPC) код с i:=i+1 и код с Inc(i) компилирует абсолютно одинаково.
Другое дело:
k:=1;
Inc(i,k);
i:=i+k;
Тут вариант с Inc точно будет быстрее работать.
 

sendsay

sendsay
Сообщения
29
Репутация
0
SyDr сказал(а):
Сомневаюсь, что именно в таком виде оно будет работать быстрее. Компилятор (FPC) код с i:=i+1 и код с Inc(i) компилирует абсолютно одинаково.
Другое дело:
k:=1;
Inc(i,k);
i:=i+k;
Тут вариант с Inc точно будет быстрее работать.
Так я о том же. ))))
 

shm_alex

Новичок
Сообщения
34
Репутация
4
IMHO, ассемблерная команда inc требует один операнд , значит она короче - загружается в память как минимум быстрее чем ассемблерная add (которая обычно требует два операнда), да и требует походу меньше тактов процессорного времени, имеется ввиду для интегеров . Правда я не уверен что интерпритатор или компилятор Autoit делает подобную оптимизацию и эти наносекунды играют хоть какую либо роль. я думаю у автоита другие узкие места по скорости.
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 711
IMHO, самое узкое место (оно же является для многих плюсом) в AutoIt - переменные типа Variant. И как следствие, ужасная скорость работы с массивами. Со всем остальным вполне можно жить, даже с отсутствием "человеческих" структур.
 

shm_alex

Новичок
Сообщения
34
Репутация
4
Yashied сказал(а):
IMHO, самое узкое место (оно же является для многих плюсом) в AutoIt - переменные типа Variant. И как следствие, ужасная скорость работы с массивами. Со всем остальным вполне можно жить, даже с отсутствием "человеческих" структур.
Да наверно это одно из узких мест ... Постоянный кастинг переменых из одного типа в другой,
Я всегда с осторожностью отношусь к операции ReDim , тк понятно что увеличение размера длинны массива на единицу требует операции выделения памяти в новом месте и копирования предыдущего содержимого массива в новое место. Хотя в последнее время под-забил на это, тип Variant -развращает и переодически пишешь $a=$b , где а и b - массивы. И что за этим выражением стоит в конце концов перестаёшь задумываться.
В моём детстве , у меня была такая машинака mk90 http://ru.wikipedia.org/wiki/%D0%AD%D0%BB%D0%B5%D0%BA%D1%82%D1%80%D0%BE%D0%BD%D0%B8%D0%BA%D0%B0_%D0%9C%D0%9A-90 со встроенным васиком на борту. Так вот я думаю что более узкое место это -интерпритируемость команд языка AutoIt .

Ещё наверно поджирает производительности всякие загрузки DLL ведь Dll надо загрузить в память , потом привести типы параметров из типа вариант привести к типам который подожрёт функция Dll-ки . Потом дёрнуть функцию dll-ки ... ну итак далее в, отличии в общем от кода который может собраться весь.

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

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4 020
Репутация
622
shm_alex
это проблема всех ЯП сверхвысокого уровня.
 

ggzgamer

Осваивающий
Сообщения
134
Репутация
23
Так оказуется можно функцию использовать в другой функции? Мне нравится такой подход, когда в конце потом программа будет чисто функцией) Или это ен правильный подход в программировании?
 
Верх