Jump to content

Leaderboard


Popular Content

Showing content with the highest reputation on 03/03/22 in all areas

  1. Lars Fosdal

    DocWiki.Embarcadero.com does Russian Roulette.

    If our web services were offline for a month, we'd be in deep shit. The monthly schedule is a normal release schedule, not an outage response schedule. The outage is annoying, but the lack of info from Idera/EMBT is catastrophic for their reputation.
  2. Lajos Juhász

    DocWiki.Embarcadero.com does Russian Roulette.

    In this case Idera/Embarcadero has no problems. The website used for new customers is working fine. It's just the docwiki that is down that is used only by customers that already paid. Why would they worry? They can get away with no roadmap, no timeframe when the critical errors will be fixed in Delphi. We that already using Delphi should know to work without a proper documentation.
  3. Lajos Juhász

    DocWiki.Embarcadero.com does Russian Roulette.

    There is no need to panic. It's out for about 2 two weeks. There was a recent webinar from Ranorex that modern IT companies now have a monthly schedule for release. So before we all panic we have just to wait another 2 weeks and see whenever that time frame is used in Idera or not.
  4. David Heffernan

    Generic sort of several "parallel" arrays?

    Is this telling you is that your data structure is wrong? What you need is a record with the 4 values and then array of that record. Then basic array sort with custom comparer gets it done. Then again, perhaps you so need direct access to contiguous arrays of each of the 4 scalars. As stated you really need a sort algo that allows you to provide both comparer and exchanger. I had such a thing once. The final approach is not to modify the arrays at all. Create an integer array with values from 0 to N-1 and then sort that using the x values to determine the order. Have the compare function return CompareSingle(x[idx[left], x[idx[right]])
  5. This is pertinent to some of the discussion here: https://stackoverflow.com/a/8550628/505088
  6. I prefer NOT to raise exceptions in constructors - class nor otherwise. It makes securing the build up of the instance hierarchy too complicated. A lack of connectivity or functionality should only be addressed at the time of use, not at the time of instancing, considering their absence may be temporary. There is one case though - during testing, assertions may be used to check for stuff that SHOULD be in place.
  7. Some bullet points: if Assigned(Obj) then Obj.Free is redundant, you can just call Obj.Free - Free is static and can be called on nil instance and also Free has nil check within before calling destructor constructors are allowed to raise exceptions destructors must never raise exceptions (without handling them within with try...except) destructors can be called on half constructed instance (if the constructor fails, destructor chain will be automatically called) and must be able to handle such scenarios without causing trouble - raising exceptions when constructor fails assignment to variable will never happen local object variables are never automatically initialized and they can contain random garbage object instance fields are always zero initialized when constructor chain is being called Because of the above correct construction pattern is var LA: TRaiseOnMinus; begin LA := TRaiseOnMinus.Create( -2 ); try //some code finally LA.Free; end; end; With multiple constructors there are multiple options, but I prefer using only single try...finally because destructors must not raise exceptions, single try finally is faster and cleaner var LA, LB: TRaiseOnMinus; begin LB := nil; LA := TRaiseOnMinus.Create( -2 ); try LB := TRaiseOnMinus.Create( -3 ); //some code finally LB.Free; LA.Free; end; end; Correct constructor and destructor for your class would be: constructor TRaiseOnMinus.Create( AParam : Integer ); begin inherited; if AParam < 0 then raise Exception.Create( 'Bum' ); FMyList := TStringList.Create; end; destructor TRaiseOnMinus.Destroy; begin FMyList.Free; inherited; end; Only if you need to do some additional work with FMyList in destructor, then you must check it for nil before using it. In such cases you can find call to Free within the same check, but not because it wouldn't work outside. destructor TRaiseOnMinus.Destroy; begin if Assigned(FMyList) then begin FMyList.DoSomethingImportant; FMyList.Free; end; inherited; end;
  8. Although that might be the case, I recently turned to form a habit that avoids anything causing exceptions inside constructors. That may also lead to avoid giving parameters to constructors - at least when they are not being handled seamlessly during the lifetime of the instance. That allows to concentrate on the real work to be done instead of figuring out some tricky handling of edge cases. LA := TRaiseOnMinus.Create; try LA.Initialize(AInputA); //<== PossibleRaise LB := TRaiseOnMinus.Create; try LB.Initialize(AInputB); //<== Possible Raise { do the normal stuff with LA and LB } finally LB.Free; end; finally LA.Free; end;
×