On Wed, 20 May 2015 14:58:57 -0700 (PDT) Guy St-Denis <
stde...@gmail.com> wrote:
GS> * why do you want to detect null?
GS> 'null', 'true' and 'false' are special values in JSON. If they can be used
GS> to convey information, we need to be able to detect them; otherwise, there
GS> is loss of information.
Right, but there is nothing equivalent in CFEngine's data types (classes
are *not* booleans), so we need a reason to have this conversion. It
seems like detecting them can be useful as a way to communicate
knowledge, so perhaps it makes sense to simply recognize them for
classes:
classes:
"isnull" expression => datatype_isnull("container[path]");
"istrue" expression => datatype_istrue("container[path]");
"isfalse" expression => datatype_isfalse("container[path]");
This can get very complicated, though. Consider the rich confusion of
Javascript with its several types of truth (see
https://stackoverflow.com/questions/801032/why-is-null-an-object-and-whats-the-difference-between-null-and-undefined
http://www.smashingmagazine.com/2011/05/30/10-oddities-and-secrets-about-javascript/
and many other fun places). There has to be a practical use for this
information, not just abstract inspection of data values.
GS> * how are they useful in the CFEngine context?
GS> The strategy I am developing uses a JSON file to specify the configuration
GS> of a host. The use of 'null' in this file can indicate that a particular
GS> configuration task does not apply, so skip the task entirely.
OK, that makes sense, though usually I would use an empty array []
instead of null to denote "no actions apply." So when you iterate over
a null value, it should be skipped? Is that not the case right now?
Let's check:
#+begin_src cfengine3
bundle agent main
{
vars:
"items" data => '[ "x", "y", null ]';
reports:
"we have item $(items)";
}
#+end_src
#+begin_src text
% cf-agent -KI -f ./
test_null.cf
R: we have item x
R: we have item y
#+end_src
So at least iteration works like you'd expect... can you show the
example that didn't?
GS> * what should they do?
GS> At this point, I would just be happy to correctly and reliably detect them.
GS> Once detected, I can decide what should happen next. Upon further
GS> investigation, I found the 'nth' function
GS> (
https://docs.cfengine.com/latest/reference-functions-nth.html) that
GS> appears to be *good enough* for my purposes right now. I have updated my
GS> issue report with more test cases using the 'nth' function in case that may
GS> be of use to someone (
https://dev.cfengine.com/issues/7194).
Hmm, that's not ideal, though, as you explain in the comments.
Actually almost exactly what you're describing already existed and was
removed from 3.6 because we couldn't find a use for it. The datatype()
function could actually tell you if a JSON element was boolean, null, a
string, etc.
Check out core.git:
commit f251521594a02a39b8998c3478d9851d46030c9b
Author: Ted Zlatanov <
t...@lifelogs.com>
Date: Thu Feb 6 09:57:23 2014 -0500
libpromises/evalfunction.c: disable datatype() pending discussion
The code is still in there, so re-enabling it is a matter of proving to
the developers that there's a practical utility to the function. From
the discussion so far, it seems that it would be useful.
On Wed, 20 May 2015 16:43:25 -0700 Aleksey Tsalolikhin <
atsalo...@gmail.com> wrote:
AT> I ran into this issue -- I'm integrating with a tool that feeds
AT> CFEngine JSON data, and the data had nulls.
AT> I asked the developer to modify the tool to always provide CFEngine
AT> sensible defaults (for example, if the JSON contained file metadata
AT> and the file mode was not specified, default to 644 instead of saying
AT> the mode is null) and he did so.
Aha, so in your case null means "don't use this attribute." That can be
done with Mustache templates but not in policy currently. The datatype()
function plus some convenience tests like I suggested above might do the
trick. Do you agree?
If so, speak up in
https://dev.cfengine.com/issues/7194 and here and let
the developers know. For what it's worth, I'm in favor of re-enabling
datatype(). Because it was already working fine before it was disabled,
maybe it could even make it into 3.7 despite the feature freeze (but the
convenience tests definitely wouldn't).
Ted