51

Re: AHK: Вопросы по объектам

Уже сообщили, я написал здесь на всякий случай, чтоб было у нас известно.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

52

Re: AHK: Вопросы по объектам

stealzy пишет:
ypppu пишет:

А объекты всегда глобальны?

Вы же вроде проверяли уже, нет?

Вот проверил. По умолчанию в функции объект локален. Если раскомментировать строку, он будет объявлен глобальным.

MyFunc()
FOR k, v in Object1.Property1
MsgBox, %k%: %v%
Return


MyFunc()
{
;Global Object1
Object1 := {}
Object1["Property1", "sector_1"] := "VALUE 1-1"
Object1["Property1", "sector_2"] := "VALUE 1-2"
FOR k, v in Object1.Property1
MsgBox, %k%: %v%
}

Правда, если посмотреть список Global Variables посреди выполнения функции, будет видно, что существует одноимённая с объектом глобальная переменная Object1.

53

Re: AHK: Вопросы по объектам

Дополнительно исследовал попавшийся баг. Результат такой.
Если внутри функции создать объект, используя в качестве части имени переменную (например Object%i%), то такой объект станет доступен вне функции (то есть глобально). Но! В отличие от объекта, изначально созданного вне функции, к нему будет невозможно обратиться, используя в качестве части имени переменную. Можно только если использовать точное имя.
Пока это писал, заметил исключение. Если где-то в коде вне функции имеется строка, в которой идёт обращение к объекту по точному имени, то появляется возможность использовать переменную как часть имени.
Короче, винегрет полный. Вывод: не используйте баги!

MyFunc(5)

;Так отдельно не работает, но заработает, если раскомментировать след. 2 строки
var := 5
FOR k, v in Object%var%.Property1
MsgBox, 1111111`n--------------`n %k%: %v%
Return


;FOR k, v in Object5.Property1 ;Так работает всегда
;MsgBox, 2222222`n--------------`n %k%: %v%


MyFunc(i)
{
Object%i% := {}
Object%i%["Property1", "sector_1"] := "VALUE 1-1"
Object%i%["Property1", "sector_2"] := "VALUE 1-2"

FOR k, v in Object%i%.Property1
MsgBox, Функция`n--------------`n %k%: %v%
}

54

Re: AHK: Вопросы по объектам

Хочу посоветоваться.
Я собираюсь передавать ссылку на объект в функцию. Насколько мне известно, чтобы функция работала напрямую с глобальной переменной, а не создавался локальный дубликат, используется ByRef. А у меня вместо переменной будет объект.
Я попробовал как с ByRef, так и без ByRef - работает одинаково хорошо.

Object1 := {}
MyFunc(Object1)


MsgBox, % Object1["Property1"]  
MsgBox, % Object1["Property2"]
Return


MyFunc(x)
{
x["Property1"] := 111
x["Property2"] := 222
MsgBox, % "Функция`n" x["Property1"]
MsgBox, % "Функция`n" x["Property2"]
MsgBox, % "Функция`n" Object1["Property1"]
MsgBox, % "Функция`n" Object1["Property2"]
}

Вопрос: это так и задумано и можно обходиться без ByRef? Или это баг?

55 (изменено: stealzy, 2018-01-02 17:47:39)

Re: AHK: Вопросы по объектам

ypppu пишет:

чтобы функция работала напрямую с глобальной переменной

Ваша ф-ия напрямую с содержимым переменной Object1 не работает.
Ф-ия читает содержащуюся в этой переменной ссылку на данные, и меняет уже эти данные.
Если вы ожидали, что ф-ия клонирует переданный ей объект, то это не так; клонируется только переменная, содержащая ссылку на объект.

Object1 := {Property1: 42, Property2: 23}
MyFunc(Object1)
MsgBox % Object1["Property1"] " " Object1["Property2"]
Return

MyFunc(x) { ; ByRef
	x := {Property1: 200, Property2: 300}
}

Вот вам еще для размышлений:

Object1 := {Property1: 42, Property2: 23}
Object2 := Object1, Object2["Property1"] := 3000
MsgBox % Object1["Property1"] " " Object1["Property2"]

Клонировать нужно явно, используя метод Clone.

56

Re: AHK: Вопросы по объектам

Давайте зайдём с другого конца. Второй пример мне по сути понятен. Но снова спотыкаюсь о терминологию, идёт какая-то нестыковка со справкой... Всё-таки переменная - это область памяти, содержащая данные, или переменная - это ссылка на область памяти, содержащую данные?

57 (изменено: ypppu, 2018-01-02 18:49:16)

Re: AHK: Вопросы по объектам

По первому примеру: я не планировал клонировать объект в функцию. В моём примере просто демонстрируется, что и Object1, и x ссылаются на одну и ту же область памяти. Только почему-то x["Property1"] выдаёт 111, а  Object1["Property1"] выдаёт пустую строку.

58 (изменено: stealzy, 2018-01-02 18:54:51)

Re: AHK: Вопросы по объектам

Хз, по ByRef разницу я показал в первом примере.
Переменная определенно имеет уникальное имя; адрес памяти(не факт что уникальный), где начинаются ее данные, и тип данных, чтобы знать на каком адресе данные заканчиваются и как данные интерпретировать. Ну и сами данные, конечно.
Когда вы пишите b:=a выделяется область в памяти (т.е. с символьным обозначением переменной связывается адрес памяти и тип), куда записывается содержимое из a.
Но если а это объект, то выделения памяти не происходит. Вместо этого с символьным обозначением b связывается тот же адрес и тип, которые записаны в a.

ypppu пишет:

почему-то x["Property1"] выдаёт пустую строку, а  Object1["Property1"] выдаёт 111

Вообще-то наоборот, так что не вижу ничего странного. Область видимости Object1 не глобальна.

ypppu пишет:

В моём примере просто демонстрируется, что и Object1 в области видимости главного потока, и x в области видимости ф-ии MyFunc() ссылаются на одну и ту же область памяти.

Лол, сколько можно говорить уже про области видимости? Пора уже новую тему создавать, развели оффтопа тут .

59

Re: AHK: Вопросы по объектам

Вот, теперь допёрло про значимость ByRef в первом примере.

Вообще-то наоборот, так что не вижу ничего странного. Область видимости Object1 не глобальна.

Опечатался, поправил. Однако, утверждение

и Object1, и x ссылаются на одну и ту же область памяти

остаётся в силе:

Local Variables for MyFunc()
--------------------------------------------------
Object1[0 of 0]: 
x: Object object {address: 0x3F31B0}


Global Variables (alphabetical)
--------------------------------------------------
0[1 of 3]: 0
ErrorLevel[1 of 3]: 0
link: Object object {address: 0x3F31B0}
Object1: Object object {address: 0x3F31B0}

60

Re: AHK: Вопросы по объектам

Наверное это плохо, потому как сбивает с толку. Я вижу в окошке «Variables and their contents», что локальный объект x хранит свои данные по тому же адресу, что и глобальных объект Object1. Я прихожу к выводу, что это один и тот же объект. Но изнутри функции добраться до глобального не удаётся. Возникает когнитивный диссонанс.

61

Re: AHK: Вопросы по объектам

Хочу проверить себя.

Эта функция пытается работать напрямую с содержимым Object1. Но это возможно только при наличии ByRef.

Object1 := {Property1: 42, Property2: 23}
MyFunc(Object1)

MsgBox % Object1["Property1"] " " Object1["Property2"]
Return


MyFunc(x) { ; ByRef
	x := {Property1: 200, Property2: 300}
}

А это называется "Функция читает ссылку на данные и меняет эти данные". ByRef не требуется.

Object1 := {Property1: 42, Property2: 23}
MyFunc(Object1)

MsgBox, % Object1["Property1"] " " Object1["Property2"]
Return


MyFunc(x) {
x["Property1"] := 200, x["Property2"] := 300
}

Всё верно? И тут, и там объект. Разница только в синтаксисе? http://smayli.ru/data/smiles/dumy-145.gif

62

Re: AHK: Вопросы по объектам

ypppu пишет:

Эта функция пытается работать напрямую с содержимым Object1. Но это возможно только при наличии ByRef.

confused_jackie_chan.jpg
Эта ф-ия меняет ссылку переменной объекта на созданный внутри ф-ии объект.
Без ByRef изменяется не оригинальная переменная, а ее локальный дубликат, который очищается на выходе из ф-ии.
С ByRef изменяется ссылка оригинальной переменной, она указывает на новые данные. Старые данные, как не имеющие ссылок на себя, очищаются сборщиком мусора.

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

63

Re: AHK: Вопросы по объектам

В первом случае при вызове функции без ByRef переданная ссылка затирается путём создания одноимённого локального объекта.
В первом случае при вызове функции с ByRef переданная ссылка становится указателем на глобальный объект. Функция редактирует его содержимое.
http://smayli.ru/data/smiles/dumy-5.gif
А во втором случае производятся действия с уже существующим объектом, ничего нового не создаётся. Поэтому ни Global, ни ByRef не требуется.

64 (изменено: stealzy, 2018-01-04 13:13:28)

Re: AHK: Вопросы по объектам

Придумалась одна аналогия.
Обычно переменные описывают как коробки и их содержимое, или как обложка книги и ее содержимое. Это упрощенная аналогия неполна, когда дело доходит до передачи значений по ссылкам.
А библиотечный каталог вполне подойдет. Каталог это журнал, в котором есть разделы, в которых записаны названия всех книг, а напротив них — расположение книги в библиотеке. В отличии от реальной библиотеки уникальна будет только комбинация раздела и названия книги (в одном разделе не может быть двух книг с одинаковым названием), местонахождение разных книг (разные названия) может быть одинаковым (и содержимое очевидно тоже), содержимое книг с разным расположением может быть одинаковым.
Теперь самое интересное — объект это не простая книга, это книга-каталог, где указаны расположения других книг в библиотеке, которые тоже могут быть каталогами.

; В журнале создается раздел MainThread и в нем создается новая запись:
Object1 := {Property1: 42, Property2: 23}
; книга Object1 находится в 7 стеллаже на 4 полке. Содержимое книги: каталог с расположением книг Property1 и Property2.
MyFunc(Object1)
; книга Object1 находится в 7 стеллаже на 4 полке. Содержимое книги: каталог с расположением книг Property1 и Property2.
MsgBox % Object1["Property1"] " " Object1["Property2"]

MyFunc(x) {
	; В журнале создается раздел MyFunc и в нем создается новая запись, адрес у нее другой, а содержимое копируется из Object1:
	; книга x находится в 9 стеллаже на 2 полке. Содержимое книги: каталог с расположением книг Property1 и Property2 скопирован из Object1.
	x := {Property1: 200, Property2: 300}
	; книга x находится в 9 стеллаже на 2 полке. Содержимое книги: каталог с новым расположением книг Property1 и Property2 (и новым содержимым).
	; На выходе из ф-ии раздел MyFunc со всеми записями очищается.
}

; В журнале создается раздел MainThread и в нем создается новая запись:
Object1 := {Property1: 42, Property2: 23}
; книга Object1 находится в 7 стеллаже на 4 полке. Каталог с расположением книг Property1 и Property2.
MyFunc(Object1)
; книга Object1 находится в 7 стеллаже на 4 полке. Каталог с новым расположением книг Property1 и Property2 (и новым содержимым).
MsgBox % Object1["Property1"] " " Object1["Property2"]

MyFunc(ByRef x) {
	; В журнале в разделе MainThread меняется запись, у книги тот же адрес, что и у Object1 (содержание уж само собой):
	; книга x находится в 7 стеллаже на 4 полке. Каталог с расположением книг Property1 и Property2.
	x := {Property1: 200, Property2: 300}
	; книга x находится в 7 стеллаже на 4 полке. Каталог с новым расположением книг Property1 и Property2 (и новым содержимым).
}
Object1 := {Property1: 42, Property2: 23}
MyFunc(Object1)
MsgBox % Object1["Property1"] " " Object1["Property2"]

MyFunc(x) {
	; Книга x находится в 9 стеллаже на 2 полке. Каталог с расположением книг Property1 и Property2 скопирован из книги Object1.
	; Если использован ByRef каталог будет оригинальным, но нам побоку, потому что мы не меняем сам каталог.
	x["Property1"] := 200, x["Property2"] := 300
	; Берем книги по расположению в записях Property1 и Property2, и заменяем на другие книги. Сами каталог (записи в нем) не трогаем.
}

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

65

Re: AHK: Вопросы по объектам

Глянул справку и стала ясна терминология autohotkey:
переменные в области видимости главного потока — глобльные,
переменные видимые во всех областях видимости — супер-глобальные. Оказывается это относительно новая фича (всего-то семь лет ), поэтому окошко «Variables and their contents» пока просто не научили показывать их отдельно.

Global superGlobal := 100
mainThread := 1
f()
MsgBox % "MainThread:`nmainThread = " mainThread "`n> mainThread2 = " mainThread2 "`nsuperGlobal = " superGlobal
j()
Return

f() {
	Global mainThread, mainThread2 := 7
	MsgBox % "f():`n> mainThread = " mainThread "`nmainThread2 = " mainThread2 "`nsuperGlobal = " superGlobal
}
j() {
	MsgBox % "j():`n> mainThread = " mainThread "`n> mainThread2 = " mainThread2 "`nsuperGlobal = " superGlobal
}

66

Re: AHK: Вопросы по объектам

stealzy пишет:

окошко «Variables and their contents» пока просто не научили показывать их отдельно

А зачем?

67

Re: AHK: Вопросы по объектам

Ну раз переменные там разделены по областям видимости, кмк логично выделить супер-глобальные в отдельную категорию.
Выше ypppu ожидал, что глобальный будет виден внутри ф-ии так же, как и супер-глобальный.

68

Re: AHK: Вопросы по объектам

Переменные там разделены по областям видимости в функциях.
По-моему всё наглядно:

ListVars
Global superGlobal := 100
f1()
f2()
return

f1()
{
   local superGlobal
   MsgBox, % superGlobal  ; локальная
}

f2()
{
   MsgBox, % superGlobal   ; глобальная
}

69

Re: AHK: Вопросы по объектам

Подождите, я ещё в библиотеке сижу! Есть пара вопросов по переменным.

Такая иллюстрация будет верна?
Может быть два одноимённых раздела?
В одном разделе может быть несколько книг?
Расположение книги - это физический адрес данных?
Название книги - это имя переменной?

Post's attachments

Схема библиотеки.PNG 17.69 kb, file has never been downloaded. 

You don't have the permssions to download the attachments of this post.

70

Re: AHK: Вопросы по объектам

Malcev, тогда беру свои слова назад.
Супер-глобальные равнозначны глобальным, объявленным внутри ф-ии словом global, выделять их отдельно не нужно.

ypppu пишет:

Однако, утверждение

    и Object1, и x ссылаются на одну и ту же область памяти

остаётся в силе:

    Local Variables for MyFunc()
    --------------------------------------------------
    Object1[0 of 0]:
    x: Object object {address: 0x3F31B0}

    Global Variables (alphabetical)
    --------------------------------------------------
    0[1 of 3]: 0
    ErrorLevel[1 of 3]: 0
    link: Object object {address: 0x3F31B0}
    Object1: Object object {address: 0x3F31B0}

Поскольку Object1 не был объявлен супер-глобальным вне ф-ии или глобальным внутри ф-ии,
ф-ия про него не знает, при упоминании создается локальная пустая переменная Object1. Поэтому внутри ф-ии Object1 никуда не указывает и

ypppu пишет:

Object1["Property1"] выдаёт пустую строку

71 (изменено: stealzy, 2018-01-04 20:29:34)

Re: AHK: Вопросы по объектам

ypppu
Вроде верна.
В моей аналогии раздел это область видимости (глобальная; текущая локальная; статические на каждую ф-ию, которые становятся локальными при входе в их ф-ию), но можно заменить разделы на корневой каталог, в котором книги - это области видимости. Не уверен, что у них есть имена, если бы имена были, к переменным внутри можно было бы адресно обратиться как к переменным массива (array.x), а это невозможно (получить доступ к глобальным изнутри ф-ии, если они не объявлены global, или получить доступ к статическим извне ф-ии).
Нет в разделе только записи о них.
Да.
Да, но названия хранятся только в журнале, на самих книгах ничего не написано (обложки нет).

72

Re: AHK: Вопросы по объектам

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

Post's attachments

Переменные.PNG 13.34 kb, file has never been downloaded. 

You don't have the permssions to download the attachments of this post.

73 (изменено: stealzy, 2018-01-04 22:16:54)

Re: AHK: Вопросы по объектам

Ну, у ф-ии не может быть своей переменной а (записи в журнале с другим адресом), если а объявлена:
супер-глобальной (global a вне ф-ий)
или глобальной (global a внутри этой ф-ии)
или вся область видимости ф-ии объявлена глобальной (global), причем переменная а не находится под local.

И ситуация как на картинке существует только если исполнение находится внутри обеих ф-ий одновременно, например Func1() вызвала Func2(). Если исполнение вне какой-либо ф-ии, тогда существуют только статические переменые этой ф-ии.

74

Re: AHK: Вопросы по объектам

Спасибо, вроде пока всё понятно с переменными. Позже займусь объектами.

75

Re: AHK: Вопросы по объектам

stealzy пишет:

Теперь самое интересное — объект это не простая книга, это книга-каталог, где указаны расположения других книг в библиотеке, которые тоже могут быть каталогами.

Значит переменная ("книга") - это просто данные (Integer, float или string), а объект - это каталог, содержащий ссылки на какие-то другие данные. Тут возникает вопрос: эти другие данные являются частью объекта? Или объект сам по себе, данные - сами по себе?

Когда читаешь про аналогию с библиотекой, складывается впечатление, что данные изначально привязаны к какому-то одному объекту. Но промелькнула мысль, что разные объекты могут ссылаться на один и тот же адрес.

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

1.1. Без ByRef. Любые манипуляции внутри функции повлияют только на копию объекта внутри функции. В этом случае адреса данных, принадлежащих локальному объекту (объекту внутри функции)  отличаются от адресов данных объекта-оригинала (объекта в глобальной видимости).

1.2 С ByRef. То же самое что и 1.1, но по завершению работы функции глобальных объект изменится - станет копией локального объекта со всеми изменениями, произведёнными в ходе работы функции.

Как в примере 1.1, так и в 1.2 используется "локальная ксерокопия" объекта.


2. Во втором примере в функцию передаётся оригинальный "каталог", то есть каталожная часть объекта. При этом данные не копируются. Функция работает напрямую с данными объекта, используя оригинальные адреса.