dynamic function calls silently fail

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

dynamic function calls silently fail

21 Oct 2019, 08:53

Dynamic function calls silently fail in AHK v1. (Fixed in AHK v2.)
Has anyone noticed this/posted re. this before?
Would this be reasonably straightforward to fix in AHK v1?
(The Sort command failing silently for custom comparator functions is another issue.)
(Something else that could have an error message: incomplete ternary operators.)

Code: Select all

;q:: ;test dynamic function calls silently fail
vFunc1 := "MyFunc"
vFunc2 := "MyNonFunc"
%vFunc1%()
%vFunc2%() ;silently fails (AHK v1)
vText := %vFunc2%() ;silently fails (AHK v1)
return

;w:: ;test Sort silently fails
vText := "a,b,c,d,e"
Sort, vText, D, F MySortFunc
MsgBox, % vText

vText := "a,b,c,d,e"
Sort, vText, D, F MyNonFunc
MsgBox, % vText
return

MyFunc()
{
	MsgBox
}

MySortFunc(a, b, c)
{
	MsgBox
}
Last edited by jeeswg on 29 Oct 2019, 12:44, edited 1 time 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: dynamic function calls silently fail

21 Oct 2019, 10:19

jeeswg wrote:
21 Oct 2019, 08:53
Has anyone noticed this
Try the documentation,
If the function cannot be called due to one of the reasons below, the evaluation of the expression containing the call stops silently and prematurely, which may lead to inconsistent results:

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

Re: dynamic function calls silently fail

21 Oct 2019, 13:13

It's on the Functions page, but it should be on the Changelog page. ;)
(If backwards compatibility is the issue, there could be a new Misc (miscellaneous) #Warn option.)
Thanks for the quote. Any ideas on the other questions?
Nice to hear from you, it seems like it's been a while. Cheers.
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: dynamic function calls silently fail

22 Oct 2019, 04:58

Dynamic function calls silently fail in AHK v1. [...]
Would this be reasonably straightforward to fix in AHK v1?
Again, the documentation,
If the function does not exist, the default base object's __Call meta-function is invoked instead.
So, for example,

Code: Select all

f(n) {
	static f := f.base.__call := "f"
	throw exception("Call to nonexistent function.", -1, n)
}
%f%()

It's on the Functions page, but it should be on the Changelog page.
:crazy: :arrow: 1.0.47.06 - March 9, 2008
Cheers.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: dynamic function calls silently fail

29 Oct 2019, 12:54

(What I meant was: rather than warnings about the issue in the documentation, it could potentially be fixed and then documented in the changelog. However, the AHK v1 base object workaround is sufficient.)

Thanks for the quote, I was not expecting anything like: 'default base object's __Call meta-function', and thus a way to override the behaviour.
This code works in AHK v1 (and does nothing in AHK v2). The official AHK v2 error message is somewhat cryptic.

Code: Select all

vFunc := "notafunc"
%vFunc%()
return

;custom AHK v1 error message: Call to non-existent function.
;official AHK v2 error message: This value of type "String" has no method named "Call".

OnCallNonFunc(vFuncName)
{
	static vIsReady := 0, vDummy := OnCallNonFunc("")
	if vIsReady
		throw Exception("Call to non-existent function.", -1, vFuncName)
	if (SubStr(A_AhkVersion, 1, 2) = "1.")
	{
		"".base.base := {__Call:"OnCallNonFunc"}
		vIsReady := 1
	}
}
By the way, I was getting unexpected error messages when using Internet Explorer sometimes, I haven't seen a consistent pattern yet, to be clear what the problem was.

What about notifying you if you pass too few/many parameters to a function in AHK v1. Can that be detected? Cheers.

Link:
[methods applied to strings by setting "".base.base e.g. StrLen and StrSplit:]
if var in/contains comma-separated list/array - Page 2 - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=37&t=43593&p=247622#p247622
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: dynamic function calls silently fail

30 Oct 2019, 01:50

This code works in AHK v1 (and does nothing in AHK v2). The official AHK v2 error message is somewhat cryptic.
It is not cryptic at all, see the documentation, :arrow: Dynamically Calling a Function and Primitive Values. Example to detect calling any value (except comobjs),

Code: Select all

%Object.GetMethod('DefineMethod')%(  Object.Prototype.base,
									'call',
									(v, p) => msgbox(v '`n' p ) )
To only detect calling strings, change Object.Prototype.base to ''.base, to detect only integers, change to 0.base, for floats .0.base, and for any number, 0.base.base. To ignore objects, change to ''.base.base. I assume this will be improved upon in future versions. Eg, by adding a ObjGetMethod function and giving a more direct access to the primitive prototypes.
What about notifying you if you pass too few/many parameters to a function in AHK v1. Can that be detected?
No, you would need to handle it in your own functions, which needs to be variadic.

Edit,

Code: Select all

{__Call:"OnCallNonFunc"}
This is a property definition in v2, not a method. You can call the value of the property, but not the property itself.

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

Re: dynamic function calls silently fail

30 Oct 2019, 05:15

- Thanks.

- Re. cryptic, if you run this 2-liner in AHK v2, and see This value of type "String" has no method named "Call"., and you're relatively new to AutoHotkey, I don't think that's going to make it very clear what the problem is.

Code: Select all

vFunc := "notafunc"
%vFunc%()
- You try to call a non-existent *function*, what does that have to do with *strings* or a method called 'Call', and where is that 'Call' method stored.
- To be useful, an error message can tell you: (a) what you did wrong, (b) (state/imply) how to fix it, (c) something else I haven't considered here.
- (Maybe you could keep the message as is, but prefix this: Call to non-existent function..)

- So maybe you can find some other arguments for amending/not amending the error message, but I think it's pretty reasonable to suggest that it's cryptic at present.
- Maybe your knowledge of AHK, special memory for remembering documentation curio, general interest in classes, and ability to infer things, makes some wordings seem easier!
- It's hard to put yourself in the shoes of others, but I try to do this, and remember experiences that I had. Cheers.
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: dynamic function calls silently fail

30 Oct 2019, 10:07

You try to call a non-existent *function*, what does that have to do with *strings* or a method called 'Call', and where is that 'Call' method stored.
The error message is accurate because the program tries to invoke the Call method of the value, but this method doesn't exist (in it or any of its bases), which also means that it isn't stored anywhere.
helgef wrote:I assume this will be improved upon in future versions. Eg, by adding a ObjGetMethod function
First, I really meant ObjDefineMethod. Second, I think I will retract my statement for now, it doesn't really make sense to me that, eg, the string prototype doesn't have a defineMethod method, but still, it can define methods by calling the defineMethod method of Object. It seems more intuitive that the definemethod/prop methods etc were methods of Any instead.

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

Re: dynamic function calls silently fail

12 Nov 2019, 08:42

I've tweaked it to list all parameters passed. It's been really useful for catching non-existent functions/methods. Thanks Helgef.

Code: Select all

OnCallNonFunc(oParams*)
{
	local
	static vIsReady := 0, vDummy := OnCallNonFunc("")
	vText := ""
	for vKey, vValue in oParams
		vText .= "`r`n" vKey " " vValue
	if vIsReady
		throw Exception("Call to non-existent function.", -1, vText)
	if (SubStr(A_AhkVersion, 1, 2) = "1.")
	{
		"".base.base := {__Call:"OnCallNonFunc"}
		vIsReady := 1
	}
}
One thing to note, if "".base.base has been changed by some other code, earlier on at loadtime, this function would override that.
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: No registered users and 148 guests