#Include <LibName> v. auto-include Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

#Include <LibName> v. auto-include  Topic is solved

08 Aug 2018, 10:03

- tl;dr when you do an auto-include, where does it put the code

- These 2 lines serve a similar purpose:
#Include <MyPrefix_MyFunc>
MyPrefix_MyFunc()
- Assuming that the function 'MyPrefix_MyFunc' isn't already defined. Both check 3 'Lib' folders for scripts called 'MyPrefix_MyFunc.ahk', and then check 3 'Lib' folders for 'MyPrefix.ahk'.

Code: Select all

;when you do either:
;#Include <MyPrefix_MyFunc>
;or (when the following function does not exist in the current script):
;MyPrefix_MyFunc()

;3 library folders are checked for, listed in the order that they are checked for:
;%A_ScriptDir%\Lib ;local library
;%A_MyDocuments%\Lib ;user library
;%A_AhkDir%\Lib ;standard library [there is no such variable in AHK at present][where 'A_AhkDir' would be the dir taken from 'A_AhkPath']

;6 files are checked for, listed in the order that they are checked for:
;%A_ScriptDir%\Lib\MyPrefix_MyFunc.ahk
;%A_MyDocuments%\Lib\MyPrefix_MyFunc.ahk
;%A_AhkDir%\Lib\MyPrefix_MyFunc.ahk
;%A_ScriptDir%\Lib\MyPrefix.ahk
;%A_MyDocuments%\Lib\MyPrefix.ahk
;%A_AhkDir%\Lib\MyPrefix.ahk

;if no matching file is found, an error is raised:
;either:
;'Error: Function library not found.'
;or:
;'Error:  Call to nonexistent function.'
- The #Include essentially copies the contents of the script, and pastes it at the location of the #Include line, any code in the included script (outside of function definitions) is executed.
- However, calling a non-existent function appears to #Include the code, but not at the point where the function was called, and not at the beginning or end of the script. Any code in the included script (outside of function definitions) is *not* executed.
- When you call a non-existent function, where does it 'put' the code, what exactly happens. Thanks.
- (I would be tempted to say that a 'return' line is placed at the bottom of the script, followed by the included script.)

Code: Select all

;script 1A ;shows 1 2 3 4
MsgBox, 1
#Include <MyPrefix_MyFunc>
MsgBox, 4

;==================================================

;script 1B ;shows 1 then 4
MsgBox, 1
MyPrefix_MyFunc()
MsgBox, 4

;==================================================

;script 2 ;location: %A_ScriptDir%\Lib\MyPrefix_MyFunc.ahk
MsgBox, 2
MyPrefix_MyFunc()
{
	SoundBeep
}
MsgBox, 3
- Links:
#Include / #IncludeAgain - Syntax & Usage | AutoHotkey
https://autohotkey.com/docs/commands/_Include.htm
Functions - Definition & Usage | AutoHotkey
https://autohotkey.com/docs/Functions.htm#lib

- [EDIT:] Note: I tried using lines like this to cause an error to get a MsgBox which lists nearby lines, to look for a 'return' line or equivalent:

Code: Select all

	var := "A_DetectHiddenWindows"
	%var% := 1
- It seems that with both approaches (#Include <LibName> and auto-include), the included file is kept 'separate' from the main file. So, the #Include functions a bit like a Gosub line. Perhaps that is a sufficient explanation.
- Thus the user has a choice: #Include <LibName> to execute any code in the included script (but not execute the function that is being looked for, you have to add a line if you want to explicitly execute it), and auto-include to execute the function (but not execute any other code in the included script).
- However, both have the effect of making any functions available for use.
- And if you use auto-include to include a function that does nothing, that has the effect of making functions available to use, without including any code the library at the specific point.

- In conclusion, an auto-include 'includes' a script, in the sense that all of its functions are made available for use, however, it does not 'copy and paste' the file contents to a specific point.
Last edited by jeeswg on 09 Aug 2018, 04:44, edited 4 times in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: #Include <LibName> v. auto-include

09 Aug 2018, 02:09

Code: Select all

;script 1A ;shows 1 then 4
MsgBox, 1
#Include <MyPrefix_MyFunc>
MsgBox, 4

;==================================================

;script 1B ;shows 1 2 3 4
MsgBox, 1
MyPrefix_MyFunc()
MsgBox, 4
Your comments are swapped.
It seems that with both approaches (#Include <LibName> and auto-include), the included file is kept 'separate' from the main file. So, the #Include functions a bit like a Gosub line. Perhaps that is a sufficient explanation.
You have drawn the wrong conclusion due to your failure to comment your code correctly it seems. Auto include enables the function, its help functions and subroutines as documented, it is not equivalent to #include where the script behaves as if the content of the included file was written at that location (as documented). In an #include, <file> is used to include a file from from one of the lib-dirs. It still behaves as #include path\file, there are no suggestion in the docs that it wouldn't.
More important to note, is that you do not know* the order of static initialistations, and hence, you should manually include functions for which this is important. *And you do not know even if you find out by testing, it is not documented, hence such tests are uninteresting.
Note: I tried using lines like this to cause an error to get a MsgBox which lists nearby lines, to look for a 'return' line or equivalent:
To get an error, use throw, and use it in the function which you know will be exectued, instead of the soundbeep.
You should remove your solved mark, the green (edit: maybe it is yellow) background is annoying, and your post contains no answer.

Cheers.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: #Include <LibName> v. auto-include

09 Aug 2018, 04:22

- (I've swapped the comments, they are in the correct order now.)
- (I've also added more explicit information about the 3 folders and the 6 files that are checked for.)
- You haven't stated anything incorrect about the conclusion, so I can't agree or disagree.
- The point about #Include is this, loosely speaking, it replaces the #Include line, 'copying and pasting' code in its place. This is the loose description stated in the documentation.
- The point about auto-include, which is triggered by the presence of un undefined function, is this, it calls the function if it finds it, but it does not, loosely speaking, 'copy and paste' code at the point where the function is called. So, where does the included code 'go'? (This is not just an academic question as your point about static initialisations suggests.)
- Thus, how to make sense of the situation.
- Well, a better way to think of it would be this: think of any files that are included as in an abstract place (the error messages even indicate a completely separate line numbering system), away from the main script.
- Both #Include and auto-include cause files to be 'present' in an abstract place. However, any #Include line has an additional effect, any time it is executed in the flow of the script, it effectively does a Gosub to the top of the included script, with a 'return' line at the bottom of the included script.
- (To use 'throw' is a good recommendation, thanks.)
- Your point about static initialisations is a good one. It establishes the important point that an auto-include can be thought of as effectively copying and pasting the script to the bottom of the script, with return lines above and below it.

Code: Select all

;main script

MsgBox, % "hello"
return

MyPrefix_MyFunc()

#Include %A_Desktop%\test include\at point v at end + static\Lib\MyOtherFunc.ahk

MyMainFunc()
{
	static vDummy := MyMainFunc()
	MsgBox, % A_ThisFunc
}

;==================================================

;results: order of MsgBoxes:
;MyOtherFunc
;MyMainFunc
;MyPrefix_MyFunc
;hello

;==================================================

/*

;==================================================

;%A_Desktop%\test include\at point v at end + static\Lib\MyOtherFunc.ahk
MyOtherFunc()
{
	static vDummy := MyOtherFunc()
	MsgBox, % A_ThisFunc
}

;==================================================

;%A_Desktop%\test include\at point v at end + static\Lib\MyPrefix_MyFunc.ahk
MyPrefix_MyFunc()
{
	static vDummy := MyPrefix_MyFunc()
	MsgBox, % A_ThisFunc
}

;==================================================

*/

;==================================================
- I think you should be more welcoming of this thread. This is the first time that I've seen fundamental points about #Include and auto-include clearly documented.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: #Include <LibName> v. auto-include

09 Aug 2018, 06:09

Hello jeeswg :wave:.
You haven't stated anything incorrect about the conclusion, so I can't agree or disagree.
I was referring to what I quoted. I'll address you explicit conclusion,
In conclusion, an auto-include 'includes' a script, in the sense that all of its functions are made available for use, however, it does not 'copy and paste' the file contents to a specific point.
The first part is clearly documented and doesn't need to be concluded, the second part (however, ...) is misleading, since in fact an auto-include causes the script to behave as if the code was present somewhere in the script, we just don't know where. And where it is put, was your question, and you have provided no answer, and you cannot. So what has been solved?
The point about auto-include, which is triggered by the presence of un undefined function, is this, it calls the function if it finds it, but it does not, loosely speaking, 'copy and paste' code at the point where the function is called. So, where does the included code 'go'?
It should be self-evident that the code isn't put where the function is called, for example, you can call a function in a lib, from inside a function, without getting an error complaining about nested functions.
It establishes the important point that an auto-include can be thought of as effectively copying and pasting the script to the bottom of the script, with return lines above and below it.
No it does not establish this, I told you explicitly that you should not conclude something like this, it is not documented, we do not know. Other than static initialisers, other positional directives should be considered. If it matters, use an explicit #include to position it appropriately. Do not rely on the misinformation in the above quote.
This is the first time that I've seen fundamental points about #Include and auto-include clearly documented.
You have an interesting view on clear documentation, I think the actual documentation, which you have also linked to, is pretty clear on the fundamentals of #include and auto-include.

Cheers.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: #Include <LibName> v. auto-include

09 Aug 2018, 06:48

- Hello Helgef!
- 'In conclusion', can just mean 'to finish', rather than meaning I have an important 'conclusion'.

- You seem to have found it quite easy to both digest and explain everything that could be directly inferred from the documentation.
- What's more, it appears that you find the points *obvious*.
- Further to that, was everything obvious to you on first reading, or has it taken some time for the information to settle.
- And even further to that, your summary is very good, in its clarity/simplicity and thoroughness, as though you had been reflecting on #Include for an extended period e.g. months.
- I think the vast majority of people would find it difficult to infer the key points as you have done. Even bright and industrious people. This is key to why I write tutorials. While I find that most pages are good enough, some pages need to be simplified in my view (e.g. things need to be more explicitly stated).
- I don't know how you find the documentation so easy to read!?

- Did you know, for example, the order of the 6 file checks that are done, because I did not feel confident about the order until I tested it myself.
- (I expected that auto-include wouldn't include code at the point that the function was called. That was stated for clarity. However, I don't recall the documentation being clear on that point.)
- I might do some tests with positional directives, to add to the static initialisation tests I've already done, that's a good idea.
- In terms of 'clearly documented', I have clarified a variety of things including the 6 file checks. These checks on #Include relate to my attempts to finish my functions tutorial. I've prepared a version of the remaining material which needs to be filled in.
jeeswg's functions tutorial - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=7&t=41823
- Btw the documentation on #Include clearly omits some crucial information, although it is available at one of the links at the bottom of the page: 'Libraries of Functions'.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: filipemb, Frogrammer and 157 guests