Jump to content

Mike Torrettinni

Members
  • Content Count

    1509
  • Joined

  • Last visited

  • Days Won

    3

Everything posted by Mike Torrettinni

  1. Not sure if this is possible, or very simple: I have record TXMLNode (a 3rd party xml library) that has function GetAttribute(name): string. I would like to use .ToInteger string helper when getting integer value, but this fails when result is empty. (I already added GetAttributeAsInteger into the source code, but from the thread the other day, suggestion was to leave the 3rd party source code intact and extend whatever needs extending) Here is a record: // very shortened version TXMLNode = record ... public function GetAttribute(const aName: string): string; end I would like to use it like : Rec.ID := vXMLNode.GetAttribute('id').ToInteger; // I prefer not to use StrToIntDef(...,0) But this fails when 'id' attribute is empty or it doesn't exist. I know how to add record helper to simple Enum, but this is not as simple. I was trying something like this, but this is not correct: TXMLNodeHelper = record helper for TXMLNode function ToInteger : string; end; function TXMLNodeHelper.ToInteger : string; begin // if Self.GetAttributeName(??) = '' then // Result := 0 // else // Result := Self.GetAttributeName(??).ToInteger; // or, in this case I would use StrToIntDef, becasue is jsut in this place and I can use .ToInteger everywehre in my code // Result := StrToIntDef(Self.GetAttributeName(??), 0); end; Any suggestion, more than welcome. If this is not possible, I will just leave modified source as it is.
  2. Yes, at the time I wasn't sure what is the right approach to start with, now I know that we were thinking the same thing, I just didn't know it 🙂 Great minds think alike 😎
  3. OK, now that I know I can't create helper on TXMLNode.GetAttribute(name): string to work with .ToInteger, I can add GetAttributeAsInteger, like this : TXMLNodeHelper = record helper for OXmlPDOM.TXMLNode function GetAttributeAsInteger(aName: string): integer; end; function TXMLNodeHelper.GetAttributeAsInteger(aName: string): integer; var vValue: string; begin vValue := Self.GetAttribute(aName); if vValue = '' then Result := 0 else Result := vValue.ToInteger; end; And now I can delete the same GetAttributeAsInteger from the source of TXMLNode and have the unit in original state, great! 🙂
  4. Yes, I see. I didn't explain it well enough, I don't need to vNode to work with custom ToInteger, but vNode.GetAttribute(name). I was afraid this is the reason. So, I can't do it, because string already has a helper.
  5. Mike Torrettinni

    Boolean short-circuit with function calls

    Don't we all? 🙂 (well, only if boss allows, of course 🙂 ) Interesting.
  6. Even if I try this: TXMLNodeHelper = record helper for TXMLNode function ToInteger(aName: string): integer; end; function TXMLNodeHelper.ToInteger(aName: string): integer; var vValue: string; begin vValue := Self.GetAttribute(aName); if vValue = '' then Result := 0 else Result := vValue.ToInteger; end; vID := vNode.GetAttribute('id').ToInteger; helper ToInteger doesn't get executed. I think something is missing here, shouldn't I be actually extending GetAttribute function and not the whole TXMLNode record?
  7. Mike Torrettinni

    Boolean short-circuit with function calls

    Interesting, but I assume this is only applicable to this exact example, right? Can this be used if A,B and C have arguments?
  8. Mike Torrettinni

    Boolean short-circuit with function calls

    Even better, yet. You are right, always room for some tweaking. Thanks.
  9. Mike Torrettinni

    Boolean short-circuit with function calls

    Actually I like both examples: function IsAnyTrue3: boolean; begin Result := false; {$B+} // Force full boolean expression evaluation Result := A or B or C or Result; {$B-} end; and function IsAnyTrue4: boolean; begin Result := false; Result := CompleteEval([Result, A, B, C]); end;
  10. Mike Torrettinni

    Boolean short-circuit with function calls

    Oh, no, I was not referring to this solution. As soon as 'clever' came up, I thought of some complicated code that uses some sort of tricks that if not docummented thoroughly, I would not recognize next week. This is good solution, but I never use these switches, so I'm afraid I would forget to use it in next example. CompleteEval seems better solution, at this moment.
  11. Mike Torrettinni

    Boolean short-circuit with function calls

    With: function CompleteEval(const aBooleanValues: array of Boolean): Boolean; var i: Integer; begin Result := false; for i := Low(aBooleanValues) to High(aBooleanValues) do if aBooleanValues[i] then Result := True; end; Right?
  12. Mike Torrettinni

    Boolean short-circuit with function calls

    How would that work to retain Result value, if True?
  13. Mike Torrettinni

    Boolean short-circuit with function calls

    Yes, too clever code usually means I will not know what it does in a week. So, I try to avoid it.
  14. Mike Torrettinni

    Boolean short-circuit with function calls

    I have nested search across a lot of fields (grouped in functions), and just trying to shorten all the code. Just trying to see if there are other options I can explore with my examples.
  15. I was looking into this, too. There was a discussion about it and a few alternatives suggested, if you find anything useful:
  16. I've been reading this article (and comments) https://community.idera.com/developer-tools/b/blog/posts/try-finally-blocks-for-protecting-multiple-resources-in-delphi Even thought it talks about protecting multiple classes (resources), I'm referring to single class: In most cases (or all) we wrap using Class after create with try... finally: var vMyClass: TMyClass; begin vMyClass := TMyClass.Create; try ... using vMyClass... finally vMyClass.Free; end; end; I assume that the only time creating class fails is when class constructor fails (it tries to execute some code that fails). Is that correct? If this is correct (that constructor is the only point of failure) then if there is no constructor defined in specific class - we don't need try...finally? Or are there other situations that creating class can fail?
  17. This question keep getting stuck in my head and I wonder which way should I do it: Does anybody have a good rule or practical advice when to use class fields directly and when to pass them as parameters, when used in class methods? For example - simple public Search method: // public method procedure TMyClass.Search(const aFieldName: string); begin fFieldName := aFieldName; // fFieldName is TMyClass field // TMyClass.SearchByFieldName SearchByFieldName; // or TMyClass.SearchByFieldName(const aFieldName: string) SearchByFieldName(fFieldName); // or SearchByFieldName(aFieldName); end; procedure TMyClass.SearchByFieldName; begin DoTheSearch1(fFieldName); DoTheSearch2(fFieldName); end; // or procedure TMyClass.SearchByFieldName(const aFieldName: string); begin DoTheSearch1(aFieldName); DoTheSearch2(aFieldName); end; I keep trying to justify one of the other approach, and a lot of times I justify passing parameters in case I need to extract method, and use it as standalone or copy to another class. In most cases this doesn't happen. I guess this is left from 'old' style where all methods were organized by units, not classes. There you need parameters. Any advice is welcome, thanks!
  18. Another good reason for parameters. I'm looking into VirtualTrees.pas (Virtual treeview) to see how it is implemented there, and I'm starting to understand. Still a long way to not question what to do every time, but with experience I will. Like everybody here is saying: there's no one exact rule, just guidelines.
  19. I have interposer class that draws custom border around TPanel. But I only want this for selected panel on the form, not all. So, I create a list of panels to be customized in xCustomizedPanels, on FormCreate. A very simple implementation: TPanel = class(Vcl.ExtCtrls.TPanel) protected procedure Paint; override; end; var xCustomizedPanels: TArray<TPanel>; procedure TPanel.Paint; var vRect: TRect; vPanel: TPanel; begin for vPanel in xCustomizedPanels do if vPanel = Self then begin vRect := GetClientRect; // Frame panel Canvas.Brush.Color := clSilver; Canvas.FrameRect(vRect); end; end; But! Isn't there a better solution so I assign customized Paint/OnPaint method only to selected panels, something like this: procedure TfrmMainForm.FormCreate(Sender: TObject); begin // assign customization Panel1.OnPaint/Paint := CustomPaint; Panel2.OnPaint/Paint := CustomPaint; ... end; Thanks for any suggestion!
  20. I'm not using any typical source control systems, like TFS, GIT... I use manual backups, but I feel like I need to switch to proper solution. I'm not sure if I really need it, and is Delphi IDE really ready to work with real source control?
  21. Mike Torrettinni

    Is interposer class really best to customize TPanel.Paint?

    But then it's not designed for any form, but just on Form1, right? I need this to be used at any form I need. OK, I like this, I will just name it Pane1.CustomBorder := True; or similar. This is still in finalizing screens the new project, so it will be changed, improved many times. I can be very picky with my UI design.
  22. Mike Torrettinni

    Is interposer class really best to customize TPanel.Paint?

    And now I have CustomPaint in its own unit, and I just use it on the Form/Frame when needed, and assign only panels that I need customized. It's a little thing, but I used to have double panels behind Edit, to make Edit look like vertical centered with grayish border (not black). Then I started used TAdvPanel, which has a single colored border, but it flickers a lot more than double TPanels. So, now I have this simple implementation. This just made my day @Fr0sT.Brutal 🙂 This is the wanted end result:
  23. What do you mean? It didn't automatically find/add github account and repositories, while other tools did. I only set github credentials and remote repositories once, then all the tools (except SmartGit) just pulled the info from git and everything was setup.
×