[SR-Dev] new operators & if($v) behaviour

Andrei Pelinescu-Onciul andrei at iptel.org
Thu Apr 30 12:53:03 CEST 2009

On Apr 28, 2009 at 13:09, Miklos Tirpak <miklos at iptel.org> wrote:
> Hi Andrei,
> On 04/28/2009 10:33 AM, Andrei Pelinescu-Onciul wrote:
> >On Apr 28, 2009 at 09:53, Miklos Tirpak <miklos at iptel.org> wrote:
> >>On 04/27/2009 04:18 PM, Juha Heinanen wrote:
> >>>Andrei Pelinescu-Onciul writes:
> >>>
> >>>>We could try some sane defaults (for if ($v)).
> >>>yes, in case there are some.
> >>>
> >>>>For example that's what perl does:
> >>>>            undefined   ""      string  0       other integer
> >>>>
> >>>>$foo eq undef   true    true    false   false   false
> >>>>$foo == undef   true    true    true    true    false
> >>>>
> >>>>$foo eq ""      true    true    false   false   false
> >>>if $foo is undefined, it is insane to me that it would be equal to empty
> >>>string "" or 0.  also comparing two undefined things should not result
> >>>in true.
> >
> >
> >Actually if you think in terms of the operators it's not. The operators
> >forces conversion of its operands to the type it expects.
> >so for eq (which used for string): $foo eq undef is in fact
> > (str) $foo  eq (str) undef , and (str) undef is "".
> >
> >
> >With undefined you have 2 options: either have valid conversion to
> >string and ints or bail out with an error. Since we cannot stop the
> >script or abort(),  even if we report an error we still have to come up 
> >with a result.
> >
> >>yes, this is really strange indeed. And ("abcd" == undef) is also true 
> >>according to the table.
> >
> >Bear in mind, that == in this case (perl) is an int operator,
> >so "abcd" == undef  is in fact (int) "abcd" == (int) undef and
> >(int) "abcd" is 0
> >(int) undef is 0
> >=> 0 == 0.
> Yes, I understand, but == was not an int operator in SER so far. So the 
> question is whether or not we want to change the script syntax, or shall 
> we keep the support for the current scripts.

For now we could keep it, but for next releases we need some changes.
We need at least different version for ==, != and + for integer and
strings. Overloading them to work for both is just broken and it will
lead to strange behaviour.
Another important change would be typed variables and avps (we would be
able to do much better error checking on the script and make life much
more easier for script writers at the cost of only having to pre-declare
the vars with the intended use type).
> >
> >>>what would make sense to me is that comparing an undefined thing to
> >>>anything that is defined, would result in false.
> >>I agree.
> >
> >I don't. We have special operators for checking if something is defined
> >or not. If you don't use it you want implicit conversion.
> >In almost all script languages, if a var is undefined then it's equal to
> >"".
> OK, this could work also in SR. Let's decide whether or not we introduce 
> another operator for string comparisons ('eq'), or stick to '=='.

I've introduced eq, ne for strings,  ieq and ine for integers. The names
are temporary as their intended use is testing (for possible
introduction in the next-next release).

> >
> >
> >If you think some other behaviour is better, please fill all the table
> > and think also about normal operations, e.g. $v int+ $x, $v str+ $x.
> >Bear also in mind that we support 2 types: int and str. We don't
> >support bool (bool is int) so all logical expressions are evaluated to
> >int (so you cannot say bool("a") == true but int("a")==0).
> >Also think about how other scripting languages handle that.
> What do you think about this? Undef is either 0 or "", and == is used 
> both for string and int.
>             undefined   ""      string  0       other integer
> $foo == undef   true    true    false   true    false

This is ok, this is the way it behaves now (on my type_conversion

> $foo == 0       true    false   false   true    false
                            this is not, but it's related to the 
                            string to int conversion (below)
> (The right value is converted to the type of the left value if 
> necessary. So "0" == 0, but "" != 0.)
> bool($foo)      false   false   true    false   true
 ^^^^^ we do not have boolean and I don't think introducing it would be
 a good ideea.

> int($foo)       0       0/error I/error 0       I
                         right now in my branch it works like this:
                         at startup you'll get an error (if the type is
                         known to be string). If the type is not known
                         (avp pvar) => I can't tell if it's an error or
                         At runtime it's 0 (for "", "abc") or I
                         (for "123"). No error is generated (it 
                         wouldn't help anyway, it's too late).

> str($foo)       ""      ""      S       "0"     "I"
> 0/error, and I/error means that the expression should be evaluated  in 
> the 'if' conditions, and in the mathematical expressions slightly 
> differently:

That's what I want to avoid, different behaviour.

> if (0 == "") -> false, (0 == "0") would be true.
> if (0 == "abcd") -> false
> if (1 == "1") -> true
> $v + "" -> $v -> I think we have no other choice.
> $v + "abcd" -> $v
> $v + "1" -> $v + 1
> I do not whether or not it's close to any scripting language, feel free 
> to tell me if it's a complete mess. But I think it's closer to the 
> current SER script language at least.

I've attached a first draft describing how type conversion and operators
work in sip-router. It describes the code on the andrei/type_conversion
branch. If I won't get strong objections, I'll merge that branch into
master (we can't waste too much time arguing, we need to have something
 sane and something that mimics perl behaviour as much as possible it
 should be at least good enough).
If people are worried about specific ser or kamailio script snippets
that won't work, then please provide some _simple_ test config that I
can use. By simple, I mean something using very few modules (only xlog &
pv would be ideal) and having something like:


if ($var != expected_value )
 xlog("L_CRIT", "BUG: sanity check 1 failed");
if ( expr2 != expectred_value)
 xlog("L_CRIT", "BUG: sanity check 2 failed");


We could collect them and use them for testing each time we do a change
to expression evaluation.


More information about the sr-dev mailing list