You wrote at
https://www.icinga.com/docs/icinga2/latest/doc/17-language-reference/#operator
{
a = 5
a = 7
}
for showing the operator.
Shouldn't that lines define a dictionary as shown in the documentation at
https://www.icinga.com/docs/icinga2/latest/doc/17-language-reference/#dictionary ?
If not where is the syntactical difference?
That is indeed a bit confusing, dictionary creation looks like that:
dict = { a = 1, b = 2}
We use { } do display commands can be used inside the configuration, to make it more clear we should rework the dictionary and array docs to show the creation of a named object and maybe remove the enclosing { }
`{ ... }' defines a local scope for this variable. It is not necessarily a dictionary with key value pairs here. Such a phrase could be added.
Just played around with the console and discovered that there's literally no difference. Local scopes are dictionaries. And @gunnarbeutner seems to be a magician.
<6> => {
<6> .. var x = 1
<6> .. a = x
<6> .. }.a
1.000000
<7> =>
FWIW there are a few subtle differences between dictionaries (even anonymous ones) and scopes even though internally they're implemented using the same AST type (DictExpression):
<11> => f = function() { 3 }
null
<12> => function() { if (5 >= 3) { 3 } }()
3.000000
<13> => { 3 }
^
Value computed is not used.
object and function) get their own local variables (var and locals) while dictionaries (and nested scoped, e.g. for if/while) do not:<14> => { var z = 3 }
{
}
<15> => { x = z }
{
x = 3.000000
}
This works because var z = 3 is really just syntactic sugar for locals.z = 3 - and locals doesn't change while we're still in the same function or console session.
this refers to the dictionary that is currently being initialized (i.e. where DictExpression::m_Inline is false):<19> => { log(typeof(this)) }
information/config: type 'Dictionary'
{
}
For scopes this usually refers to something else, e.g. the object that is being created (for apply or `object) or - for functions - the containing scope in which the function was created:
<24> => function() { log(this == globals) }()
information/config: true
null
Or, for prototype methods or functions which are called via call or callv, this can be whatever the function is invoked on:
<27> => function() { len(this) }.call("Hello World!")
12.000000
<35> => String.prototype.xlen = function() { len(this) }
null
<36> => "Hello World!".xlen()
12.000000
Most helpful comment
FWIW there are a few subtle differences between dictionaries (even anonymous ones) and scopes even though internally they're implemented using the same AST type (
DictExpression):objectandfunction) get their own local variables (varandlocals) while dictionaries (and nested scoped, e.g. forif/while) do not:This works because
var z = 3is really just syntactic sugar forlocals.z = 3- andlocalsdoesn't change while we're still in the samefunctionor console session.thisrefers to the dictionary that is currently being initialized (i.e. where DictExpression::m_Inline is false):For scopes
thisusually refers to something else, e.g. the object that is being created (forapplyor `object) or - for functions - the containing scope in which the function was created:Or, for prototype methods or functions which are called via
callorcallv,thiscan be whatever the function is invoked on: