Mike Torrettinni 198 Posted June 18, 2020 20 minutes ago, Vandrovnik said: In 10.3.3, it is better, usually rename finds all places, but sometimes it does not and finds for example just 10 of 30. Skipping 10.3.x altogether. Will see how 10.4 updates will be successful. Share this post Link to post
Rollo62 502 Posted June 19, 2020 (edited) 7 hours ago, Vandrovnik said: In 10.3.3, it is better, usually rename finds all places, but sometimes it does not and finds for example just 10 of 30. Exactly, to find something is not very reliable or convenient, with Rx10.4 LSP this is getting somewhat better in the right direction, but not perfect. Maybe Uwes MMX-Tool fills that gap, but I'm still learning howto use it at best. Still I'll do a lot of intensive "search and replace" with external tools, which gave me much better feeling of reliability. Edited June 19, 2020 by Rollo62 Share this post Link to post
Attila Kovacs 617 Posted June 19, 2020 While refactoring is still not perfect and does not work every time, I could improve it with turning off "View references before refactoring". 1 Share this post Link to post
Uwe Raabe 1888 Posted June 19, 2020 4 hours ago, Rollo62 said: Maybe Uwes MMX-Tool fills that gap, Not really. Besides only working inside the current unit, ist is merely a find and replace respecting some scope. 1 Share this post Link to post
Arnaud Bouchez 380 Posted June 25, 2020 Strong typing may be a good idea in some context. For instance, in DDD (Domain Driven Design) you should better define your genuine types. Instead of writing: type TUser = record Name: string; FirstName: string; end; You should rather define: type TUserName = type string; TUserFirstName = type string; TUser = record Name: TUserName; FirstName: TUserFirstName; end; TUsers = type TArray<TUser>; and so on for any service methods. Such strong typing (T* = type ### defines its own strong type) helps maintaining complex code. I always let people remember the https://en.wikipedia.org/wiki/Mars_Climate_Orbiter disaster. A strong type (as it should have been if ADA would still have been used for the software) would have ensured that the force would use the same unit in the inter-module computation (english vs metric systems). Specific types may help e.g. for "Design by contract". Of course, for a DTO you may just use plain string/TArray<string>. But if you want to have some maintainable long-term code, consider define your own types. See e.g. http://blog.synopse.info/post/2019/09/18/Introducing-Kingdom-Driven-Design-at-EKON-23 1 Share this post Link to post
Mike Torrettinni 198 Posted June 26, 2020 6 hours ago, Arnaud Bouchez said: TUserName = type string; OK, I've never seen this, and the more I read about it, the more confused I am what it is used for. I understand it becomes new string type, compatible with just string. But I don't see how it's useful. Share this post Link to post
Guest Posted June 26, 2020 2 hours ago, Mike Torrettinni said: OK, I've never seen this, and the more I read about it, the more confused I am what it is used for. I understand it becomes new string type, compatible with just string. But I don't see how it's useful. It is useful and will save you time in long run and will avoid bunch of problem down the road, i use sometimes to replace even simpler types like Integer, for me changing an existing code is time consuming and tend to be error prone more than writing new one, here an example on how this save time TSessionID been used to replace Integer, forcing myself to use helper with it, that server was and still using it for identifying the connection sessions per run and it was initialized to 0 per restart, years later the server become 64bit and i didn't touch anything except the session type in the code making it Int64, was good for a year or two then the need for longer and unique Session to be permanent over time, Int64 will not do it, server now is using cloud storage and it is more than one EXE running on different machines and in need to coordinate with some data bank, so simple and short types are out of the question, now guess how much time it took me converting TSessionID into TGUID that also have the creation time, it was less than 3 minutes to make sure the helper is comparing and returning right sort of readable string format and vice versa. In fact i was using TSessionID for TCP connections and TUserID for users per authorization, both were Integer in the past and both are are TGUID now, think about that, i even can't mix between them, leave them TGUID and imagine one fogy brain morning what damage you can cause, TSessionID is created per TCP session while TUserID are grabbed from DB. On other hand i didn't do that in the past for the user name and was using short strings to be fixed maximum size and fit in record nicely, because the DB user table was cached in the memory in full, it was time consuming changing anything about it, caused many bugs over time, i forced later to use strong type for it and forgot that problem, till this day every time i come across code that handle the user name i double check it in fear it still buggy, while i don't even think about session id or user id, because they were there from beginning. Share this post Link to post
David Heffernan 2300 Posted June 26, 2020 Distinct types don't give you type safety when used with integers and strings. These distinct types are still assignment compatible. There is a use in type identity for design time property editors. If you want type safety for assignment you'd need to wrap in a record. 3 Share this post Link to post
Stefan Glienke 1905 Posted June 26, 2020 (edited) 13 hours ago, Arnaud Bouchez said: TUsers = type TArray<TUser>; Sorry to disappoint you but that does not compile but raises [dcc32 Error] E2574 Instantiated type can not be used for TYPE'd type declaration 13 hours ago, Arnaud Bouchez said: A strong type (as it should have been if ADA would still have been used for the software) would have ensured that the force would use the same unit in the inter-module computation (english vs metric systems). Specific types may help e.g. for "Design by contract". Too bad we are working with Delphi where it does not matter because I can still assign a TUserName to TUserFirstName Edited June 26, 2020 by Stefan Glienke 2 Share this post Link to post
Mike Torrettinni 198 Posted June 26, 2020 5 hours ago, Kas Ob. said: TSessionID been used to replace Integer You are talking about TSessionID = integer; or TSessionID = type integer; ? I understand the use of first one, but not the second one. Share this post Link to post
Guest Posted June 26, 2020 (edited) 14 minutes ago, Mike Torrettinni said: You are talking about TSessionID = integer; or TSessionID = type integer; ? First one. Edit This will not prevent assignment, but will at least make you wonder in case you forgot or this is not your code, what on earth is TSessionID, so clicking find declaration you will it is simple integer but with note/comment like Use it with this helper or with that class, or don't touch its value, use functions YYY1,YYY2 in unitX to create, assign or compare Edited June 26, 2020 by Guest Share this post Link to post
Mike Torrettinni 198 Posted June 26, 2020 11 minutes ago, Kas Ob. said: First one. Edit This will not prevent assignment, but will at least make you wonder in case you forgot or this is not your code, what on earth is TSessionID, so clicking find declaration you will it is simple integer but with note/comment like Use it with this helper or with that class, or don't touch its value, use functions YYY1,YYY2 in unitX to create, assign or compare Great, thank you! Do you have a real case scenario for using the second option, TSessionID = type integer; ? Share this post Link to post
Guest Posted June 26, 2020 Just now, Mike Torrettinni said: Do you have a real case scenario for using the second option, TSessionID = type integer; ? Nope, i like to keep things simple, used few times in the past and regret it later. Share this post Link to post
David Heffernan 2300 Posted June 26, 2020 16 minutes ago, Mike Torrettinni said: Do you have a real case scenario for using the second option, TSessionID = type integer; ? For integer, due to assignment compatibility rules of the language, the only use is to provide a distinct type identity to be used in RTTI settings. For instance if you wanted to have a separate design time property editor for this type. Share this post Link to post
Mike Torrettinni 198 Posted June 26, 2020 12 minutes ago, David Heffernan said: to be used in RTTI settings Thanks! Sometimes such clear wording makes all the difference. Yesterday reading in official help and SO answers, I just didn't get it. Now, re-reading the same again, it makes sense. Share this post Link to post
Arnaud Bouchez 380 Posted June 27, 2020 (edited) 22 hours ago, Stefan Glienke said: Sorry to disappoint you but that does not compile but raises [dcc32 Error] E2574 Instantiated type can not be used for TYPE'd type declaration The new features of this compiler are just untested/unfinished... Even the type helpers are broken with sub-types: if you define TMyInteger = type integer then you can't use myinteger.ToString... Non-inheritance is a "feature" which IMHO is wrong. What always work, and is the very same, is to write: TUsers = array of TUser; > Too bad we are working with Delphi where it does not matter because I can still assign a TUserName to TUserFirstName Yes, only var/out variables have compile-time strong checking... But at least you can read the code and verify the consistency either since the type (and RTTI) are explicit. And refer to the type definition comment as documentation. And it also helps writing more natural code, by having the type defined in the time, not in the parameter I prefer: function CopySession(source, dest: TSessionID): boolean; .... property session: TSessionID; instead of function CopySession(sourceSessionID, destSessionID: integer): boolean ... property sessionID: integer; Edited June 27, 2020 by Arnaud Bouchez 3 Share this post Link to post