Forum > General

mormot2 JSON + If + and = wtf?

(1/2) > >>

commanderz:
Hello ,
I'm messing around with mormot2 JSON here and noticed a very strange thing (which works fine in delphi)
In the following code, I try to parse JSON using the rather convenient "variant way".
And I have a question why the lines are marked as //ok!!!! and //error!!! that's how they behave.
I can argue that both methods will work in delphi, but for some reason only one in lazarus (fpc).
 More details:
the problem in my opinion is that lazarus (fpc ) tries to execute the next "and" operator even though the previous one returned false,
which is enough for the whole expression to be false .  :o
  Maybe there is some optimizing parameter for the compiler that I omitted?  :-[

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} --- //for those who are too lazy to read the code, we have the following values:  J._Count=2  J._(2)=nil //now you see why we check these conditions before calling non-existent values in 71, 74 lines Next is our program, a simple form with two memos and a button

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---unit Unit1; {$mode objfpc}{$H+} interface uses  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls  ,mormot.core.base  ,mormot.core.text  ,mormot.core.json  ,mormot.core.variants  ;  type   { TForm1 }   TForm1 = class(TForm)    Button1: TButton;    Memo1: TMemo;    Memo2: TMemo;    procedure Button1Click(Sender: TObject);  private   public   end; var  Form1: TForm1; implementation {$R *.lfm} { TForm1 } procedure TForm1.Button1Click(Sender: TObject);Var S: RawUtf8;    J: Variant;    i:integer;    R:  TTestArray;begin memo1.text='[{"name":"ABC"  ,"Record01":{"ax":"2022-05-11T23:59:56.971655858Z","bx":"abc","cx":123.45,"dx":123,"ex":["abc","def"],"fx":12345,"gx":"ABC"}  ,"Record02":{"az":"2022-05-11T23:59:56.971655858Z","bz":"def","cz":678.90,"as":456,"ez":"ABC","fz":123.57,"gz":2,"hz":["HIJ"]}  ,"Record03":{"ad":"2022-05-11T23:59:00Z","bd":123.45,"cd":456.78,"dd":101.01,"ed":234.56,"fd":1234}  ,"Record04":{"ad":"2022-05-11T04:00:00Z","bd":789.01,"cd":345.56,"dd":901.23,"ed":146.53,"fd":4567}  ,"Record05":{"ad":"2022-05-10T04:00:00Z","bd":890.12,"cd":345.67,"dd":890.13,"ed":456.87,"fd":90123} },{"name":"DEF"  ,"Record01":{"ax":"2022-05-11T23:59:52.111529728Z","bx":"def","cx":678.9,"dx":456,"ex":["ghi","jkl"],"fx":67890,"gx":"DEF"}  ,"Record02":{"az":"2022-05-11T23:59:59.061193216Z","bz":"ghi","cz":123.45,"as":789,"ez":"DEF","fz":456.89,"gz":1,"hz":["KLM"]}  ,"Record03":{"ad":"2022-05-11T23:59:00Z","bd":678.90,"cd":901.23,"dd":202.02,"ed":789.01,"fd":5678}  ,"Record04":{"ad":"2022-05-11T04:00:00Z","bd":234.56,"cd":789.01,"dd":456.78,"ed":456.78,"fd":8901}  ,"Record05":{"ad":"2022-05-10T04:00:00Z","bd":345.67,"cd":890.12,"dd":456.78,"ed":867.91,"fd":45678} }]'; s := memo1.text;  J := TDocVariant.NewJson(S); memo2.lines.add('Variant way================='); memo2.lines.add('J kind='+intToStr(J._Kind)+', J count='+intToStr(J._Count)); if (J.Exists('none')) then memo2.lines.add('J.none='+J.none); //V1._Kind  V1._Count  //ok!!!: if ((J._Kind=2)and(J._Count>2)and( J._(2)<>nil) ) then if (J._(2).Exists('name')) then memo2.lines.add('J._(1).name='+J._(1).name);  //error!!!: if ((J._Kind=2)and(J._Count>2)and( J._(2)<>nil)and(J._(2).Exists('name')) ) then memo2.lines.add('J._(1).name='+J._(1).name); //ok: if ((J._Kind=2)and(J._Count>2) ) then if (J._(1).Exists('name')) then memo2.lines.add('J._(1).name='+J._(1).name); //ok: if (J._(0).Exists('name')) then memo2.lines.add('J._(0).name='+J._(0).name); if (J._(1).exists('name')) then memo2.lines.add('J._(1).name='+J._(1).name); if (    (J._(1).exists('Record01'))     and (J._(1).Record01._Count>0)    ) then memo2.lines.add('J._(1).Record01.ex._(0)='+J._(1).Record01.ex._(0)); end; end.  



p.s Using in this code mormot2 JSON synapse help link:
https://blog.synopse.info/?post/2014/02/25/TDocVariant-custom-variant-type

PascalDragon:
It could be that you've encountered a bug for which we're looking for a reproducible test case (see here). Though it would be nicer if we could reproduce it without a dependency on mORMot...

Joanna:
I vaguely remember that the default behavior of pascal is to stop evaluating Boolean expressions when the answer becomes known but there was some setting somewhere to make it evaluate entire expression anyway ?
 I’m not sure why anyone would want to do this but somewhere in some compiler of pascal it was an option. I wish I could remember more about it.

TRon:

--- Quote from: Joanna on February 07, 2023, 02:57:29 pm ---I vaguely remember that the default behavior of pascal is to stop evaluating Boolean expressions when the answer becomes known but there was some setting somewhere to make it evaluate entire expression anyway ?
 I’m not sure why anyone would want to do this but somewhere in some compiler of pascal it was an option. I wish I could remember more about it.

--- End quote ---
You didn't even bother to click the link did you ?

Everything relevant is already provided by PascalDragon including the refreshment for your memory so that you do not have to bother reading the manual concerning compiler directives.

440bx:

--- Quote from: Joanna on February 07, 2023, 02:57:29 pm ---I wish I could remember more about it.

--- End quote ---
You're thinking about $B directive.  An explanation for it is at https://www.freepascal.org/docs-html/current/prog/progsu4.html

Navigation

[0] Message Index

[#] Next page

Go to full version