Jump to content

Bill Meyer

Members
  • Content Count

    651
  • Joined

  • Last visited

  • Days Won

    12

Bill Meyer last won the day on October 26 2022

Bill Meyer had the most liked content!

Community Reputation

333 Excellent

1 Follower

Technical Information

  • Delphi-Version
    Delphi 10.2 Tokyo

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Disappointing, as other Tryxxx routines avoid raising exceptions.
  2. Bill Meyer

    DelphiLint v1.0.0 released!

    Issue #26 reported. Issue #27 for documentation.
  3. Bill Meyer

    DelphiLint v1.0.0 released!

    Download the packaged zip for your Delphi version from the latest release, or build from source. Unzip the folder and run the included install.bat script. Done! Well, no. Then I run Delphi 11.3, and get a dialog wanting me to set up external resources. I did start by installing the JRE. The dialog says that, by default, JAVA_HOME is used. But Select override is focused, and wants me to point where? I do not find a JAVA_HOME environment variable, and one might hope that the startup code would solve that for me. I am guessing this wants the location of javaw.exe? Or java.exe? I find no enlightenment on this in the readme on github, either. I am not a Java user, and could wish for a more useful explanation in the dialog. Since my guess proved not to solve the problem, I emphasize the wish for better guidance.
  4. Bill Meyer

    Delphi Low-code No-code?

    Depending on the corporate view of dev tools as investment.
  5. Before anyone gets too upset, my perspective is based on dealing with legacy code you have come into. There are numerous advantages to encapsulating global variables. Not only do you establish a measure of access control, but if you expose them as properties with getters and setters, you can easily set breakpoints to discover points of interaction. Equally, you could introduce logging. But even without those benefits, you will be altering the calling code to reference MyGlobals.SomeState, rather than simply SomeState. Once you have accomplished that tedious task, it is also a simple matter to search for all such references by searching on MyGlobals. Other benefits will become apparent as you work through things.
  6. Bill Meyer

    How do I upgrade an old 2007 project ?

    Components may be a barrier to doing the complete transition in one step. In particular, there is no release version of DevExpress which supports both D2007 and the latest compilers. If DevExpress is an issue, then it may be best to update to the last version which supports D2007 and do the conversion of grids and other components which were removed later. The recent versions do not offer dxGrid, for example, but require changing to the cxGrid, which may be a good deal of work, depending mainly on event handlers used, as the architecture changed between dxGrid and cxGrid.
  7. Bill Meyer

    How do I upgrade an old 2007 project ?

    I am curious. How many source files in the project?
  8. In tackling large legacy projects, I have seen many cycle chains which exceed 100 units. The graphs are pretty, but when the magnitude of the problems is so great, the graphical interface seems to me to be less than effective. I have dealt with cycle reduction painfully, sometimes getting lucky, and other times finding obvious failures to separate concerns. But in many cases, I have been defeated by the challenge of finding a starting point. And nice as it is to clean up some modules, when the result doesn't alter the cycle count, it becomes hard to maintain your enthusiasm.
  9. Absolutely! But as you point out, it is also a serious task to refactor such things.
  10. Let me make a rash assertion. If you have a large project in which some modules are large (>15K lines) and contain many (>200) uses references, then you are referencing some of them simply to gain access to relatively simple types. Move those to other modules with no code. Modules of types and consts can be global with no negative impact. But when those declarations are no longer found in massive units, you will begin to see your uses clauses shrink.
  11. One of the issues is that in a large project with many circular references, that log will show modules appearing again and again. In one large project, I found over 20,000 such references, and a cold build was up to eight minutes. Reducing the circular references by about 25% brought the build time down to about a minute. And the time was stable over several builds in a session, where with 20K+ it had been increasing on successive builds. MMX does produce a report of circularity chains. It is large, and not friendly to humans, but it is easy to parse, and I built a simple tool which delivers in a grid the counts for each of the modules with circular references, and which can compare two reports, which is useful as you continue to work on the project.
  12. I might go so far as to call circular unit references code rot. And they are one of the most common issues in legacy code, in my experience.
  13. There can be exceptional cases which justify sparing use of circular dependencies. Donald Knuth makes the point with regard to sorting algorithms. @Stefan Glienke has also argued for such cases. My point, and what @Uwe Raabe was speaking very explicitly about is large programs where circularity is commonplace, and not at all exceptional. There is no rational case which can support that practice. In the majority of cases, circular references are needed because of badly organized code modules. And I say that based on thousands of modules and millions of lines of code, over a period of 15+ years.
  14. So yesterday I began to have this problem with 11.1 in a VM. Did some searching this morning, and that led me to this thread, which I recall reading when it was new. My situation is not identical, Lars, as I do not see the color of gutter dots change. But breakpoints become non-functional, depending on where they are. I can break in the DPR, or in the main form. But somewhere beyond those areas, the breakpoints do not trigger. Have you discovered the cause? I was going to check include remote symbols, and found it already checked, so that is not a solution here.
  15. OK, I have been merely watching, but decided finally to take the plunge, not in ChatGPT, but with "the new Bing." My input: Using Delphi, write a class to provide CRUD operations on a dataset. Bing's response: Sure! Here's an example of a Delphi class that provides CRUD operations on a dataset: ```delphi type TMyClass = class private FDataSet: TDataSet; public constructor Create(ADataSet: TDataSet); function ReadData(AID: Integer): Boolean; function CreateData(AData: TMyData): Boolean; function UpdateData(AID: Integer; AData: TMyData): Boolean; function DeleteData(AID: Integer): Boolean; end; constructor TMyClass.Create(ADataSet: TDataSet); begin FDataSet := ADataSet; end; function TMyClass.ReadData(AID: Integer): Boolean; begin Result := False; FDataSet.Close; FDataSet.Params.Clear; FDataSet.Params.CreateParam(ftInteger, 'ID', ptInput); FDataSet.ParamByName('ID').AsInteger := AID; FDataSet.Open; if not FDataSet.IsEmpty then Result := True; end; function TMyClass.CreateData(AData: TMyData): Boolean; begin Result := False; FDataSet.Close; FDataSet.Params.Clear; FDataSet.Params.CreateParam(ftString, 'Name', ptInput); FDataSet.ParamByName('Name').AsString := AData.Name; FDataSet.Params.CreateParam(ftString, 'Description', ptInput); FDataSet.ParamByName('Description').AsString := AData.Description; FDataSet.ExecSQL; if FDataSet.RowsAffected > 0 then Result := True; end; function TMyClass.UpdateData(AID: Integer; AData: TMyData): Boolean; begin Result := False; FDataSet.Close; FDataSet.Params.Clear; FDataSet.Params.CreateParam(ftString, 'Name', ptInput); FDataSet.ParamByName('Name').AsString := AData.Name; FDataSet.Params.CreateParam(ftString, 'Description', ptInput); FDataSet.ParamByName('Description').AsString := AData.Description; FDataSet.Params.CreateParam(ftInteger, 'ID', ptInput); FDataSet.ParamByName('ID').AsInteger := AID; FDataSet.ExecSQL; if FDataSet.RowsAffected > 0 then Result := True; end; function TMyClass.DeleteData(AID: Integer): Boolean; begin Result := False; FDataSet.Close; FDataSet.Params.Clear; FDataSet.Params.CreateParam(ftInteger, 'ID', ptInput); FDataSet.ParamByName('ID').AsInteger := AID; FDataSet.ExecSQL; if FDataSet.RowsAffected > 0 then Result := True; end; ``` I hope this helps! Let me know if you have any other questions. Source: Conversation with Bing, 4/5/2023(1) How do I solve the "Cannot perform this operation on a closed dataset .... https://stackoverflow.com/questions/6774634/how-do-i-solve-the-cannot-perform-this-operation-on-a-closed-dataset-with-borl Accessed 4/5/2023. (2) Leveraging ChatGPT to generate a Delphi class along with CRUD code from .... https://www.ideasawakened.com/post/leveraging-chatgpt-to-generate-a-delphi-class-along-with-crud-code-from-a-table-schema Accessed 4/5/2023. (3) Beginner Delphi Tutorial on CRUD/Add, Edit, Delete and ... - YouTube. https://www.youtube.com/watch?v=h2rZTgEJDPg Accessed 4/5/2023. (4) GitHub - onryldz/express-dataset: Delphi JSON - CRUD DataSet. https://github.com/onryldz/express-dataset Accessed 4/5/2023. I must say that the footnotes impressed me, not only by their inclusion, but the fact that one article cited was from today. Let me add that I have not looked closely, nor even run it through Delphi looking for errors. However, neither did I need to refine my request, nor work around any limit to emitted line count.
×