Benny Amorsen
2009-Jul-22 12:43 UTC
[asterisk-users] ExecIf and empty variables (early evaluation)
Imagine that you have this code: exten => _X!,n,Set(foo=${QUEUE_WAITING_COUNT(${QueueName})})) If ${QueueName} happens to be unset, this will cause a warning: [Jul 22 14:26:17] ERROR[8114]: app_queue.c:5187 queue_function_queuewaitingcount: QUEUE_WAITING_COUNT requires an argument: queuename The obvious solution: exten => _X!,n,ExecIf($["${QueueName}" != ""]?Set(foo=${QUEUE_WAITING_COUNT(${QueueName})})) However, this doesn't actually work! Functions and variables on the right hand side are evaluated BEFORE it is decided whether it needs to be executed at all! This is fairly harmless in this case, in that it just causes a warning. However, what about this case? exten => _X!,n,ExecIf($[${bar} < 10]?Set(foo=${INC(bar)})) Which you can argue that this code is in poor taste, it is definitely surprising that INC is evaluated in this case, changing ${bar} even if ${bar} >= 10. It probably isn't possible to do something about this, but now you have all been warned... This could be a good reason for avoiding side effects in functions, and thereby banning ${INC()} /Benny
Danny Nicholas
2009-Jul-22 13:30 UTC
[asterisk-users] ExecIf and empty variables (early evaluation)
You should submit this as a bug. It may or may not get fixed, but it definitely won't until someone reports it or takes it upon themselves to fix it. -----Original Message----- From: asterisk-users-bounces at lists.digium.com [mailto:asterisk-users-bounces at lists.digium.com] On Behalf Of Benny Amorsen Sent: Wednesday, July 22, 2009 7:44 AM To: asterisk-users at lists.digium.com Subject: [asterisk-users] ExecIf and empty variables (early evaluation) Imagine that you have this code: exten => _X!,n,Set(foo=${QUEUE_WAITING_COUNT(${QueueName})})) If ${QueueName} happens to be unset, this will cause a warning: [Jul 22 14:26:17] ERROR[8114]: app_queue.c:5187 queue_function_queuewaitingcount: QUEUE_WAITING_COUNT requires an argument: queuename The obvious solution: exten => _X!,n,ExecIf($["${QueueName}" !""]?Set(foo=${QUEUE_WAITING_COUNT(${QueueName})})) However, this doesn't actually work! Functions and variables on the right hand side are evaluated BEFORE it is decided whether it needs to be executed at all! This is fairly harmless in this case, in that it just causes a warning. However, what about this case? exten => _X!,n,ExecIf($[${bar} < 10]?Set(foo=${INC(bar)})) Which you can argue that this code is in poor taste, it is definitely surprising that INC is evaluated in this case, changing ${bar} even if ${bar} >= 10. It probably isn't possible to do something about this, but now you have all been warned... This could be a good reason for avoiding side effects in functions, and thereby banning ${INC()} /Benny _______________________________________________ -- Bandwidth and Colocation Provided by http://www.api-digital.com -- asterisk-users mailing list To UNSUBSCRIBE or update options visit: http://lists.digium.com/mailman/listinfo/asterisk-users
Philipp Kempgen
2009-Jul-22 15:30 UTC
[asterisk-users] ExecIf and empty variables (early evaluation)
Benny Amorsen schrieb:> Imagine that you have this code: > > exten => _X!,n,Set(foo=${QUEUE_WAITING_COUNT(${QueueName})})) > > If ${QueueName} happens to be unset, this will cause a warning: > > [Jul 22 14:26:17] ERROR[8114]: app_queue.c:5187 > queue_function_queuewaitingcount: QUEUE_WAITING_COUNT requires an > argument: queuename > > The obvious solution: > > exten => _X!,n,ExecIf($["${QueueName}" != ""]?Set(foo=${QUEUE_WAITING_COUNT(${QueueName})})) > > However, this doesn't actually work! Functions and variables on the > right hand side are evaluated BEFORE it is decided whether it needs to > be executed at all! > > This is fairly harmless in this case, in that it just causes a warning.You could split it up into multiple statements: if ("${QueueName}" != "") { Set(foo=${QUEUE_WAITING_COUNT(${QueueName})}); } else { Set(foo=-1); // or whatever } (don't remember how to write that in extensions.conf format) Pros: - conditional evaluation - more readable (ExecIf() looks ugly) Cons: - more statements - less readable then a ternary conditional expression in "real" programming languages: foo = ($queuename != "" ? queue_waiting_count($queuename) : -1)> However, what about this case? > > exten => _X!,n,ExecIf($[${bar} < 10]?Set(foo=${INC(bar)})) > > Which you can argue that this code is in poor taste, it is definitely > surprising that INC is evaluated in this case, changing ${bar} even if > ${bar} >= 10. > > It probably isn't possible to do something about this, but now you have > all been warned... This could be a good reason for avoiding side effects > in functions, and thereby banning ${INC()}Ban ExecIf(). Use AEL. Use if(){} blocks. :-) In order to use control structures like "if .. else"/"switch .. case" it's almost necessary to write your dialplan in AEL because the same thing is so incredibly hard to read and write in extensions.conf format (GotoIf()). Although very basic dialplans look good in extensions.conf my suggestion is to use AEL and let the AEL compiler figure out how to translate that into an Asterisk dialplan. Philipp Kempgen -- AMOOMA GmbH - Bachstr. 126 - 56566 Neuwied -> http://www.amooma.de Gesch?ftsf?hrer: Stefan Wintermeyer, Handelsregister: Neuwied B14998 Asterisk: http://the-asterisk-book.com - http://das-asterisk-buch.de Videos of the AMOOCON VoIP conference 2009 -> http://www.amoocon.de --
Leif Madsen
2009-Jul-23 12:24 UTC
[asterisk-users] ExecIf and empty variables (early evaluation)
Benny Amorsen wrote:> Imagine that you have this code: > > exten => _X!,n,Set(foo=${QUEUE_WAITING_COUNT(${QueueName})})) > > If ${QueueName} happens to be unset, this will cause a warning: > > [Jul 22 14:26:17] ERROR[8114]: app_queue.c:5187 > queue_function_queuewaitingcount: QUEUE_WAITING_COUNT requires an > argument: queuename > > The obvious solution: > > exten => _X!,n,ExecIf($["${QueueName}" != ""]?Set(foo=${QUEUE_WAITING_COUNT(${QueueName})})) > > However, this doesn't actually work! Functions and variables on the > right hand side are evaluated BEFORE it is decided whether it needs to > be executed at all!Try this, as I think the IF() function works differently (I could be wrong though): exten => _X!,n,Exec(${IF($["${QueueName}" != ""]?Set(foo=${QUEUE_WAITING_COUNT(${QueueName})}:NoOp())}) Leif Madsen. http://www.leifmadsen.com http://www.oreilly.com/catalog/asterisk