Search This Blog
Wednesday, August 2, 2023
What Are the Greenest Programming Languages?
Monday, July 31, 2023
EasyDBMigrator
EasyDbMigrator is a database migration library designed for Delphi. It simplifies database evolution and is available in both 32-Bit and 64-Bit versions.
Find it here: https://github.com/AliDehbansiahkarbon/EasyDBMigrator
Migration:
It uses a concept called Migration, migrations are structured objects designed to alter your database schema. They provide an alternative to creating numerous SQL scripts requiring manual execution by every developer involved.
Name | Simple | Advanced | ORM | LargeScript Execution |
---|---|---|---|---|
Microsoft SQL SERVER | ||||
MySQL | ||||
MariaDB | ✅ | |||
PostgreSQL | ✅ | - | - | |
Oracle | - | - |
Delphi XE5
Delphi XE6
Delphi XE7
Delphi XE8
Delphi 10 Seattle
Delphi 10.1 Berlin
Delphi 10.2 Tokyo
Delphi 10.3 Rio
Delphi 10.4 Sydney
Delphi 11.0 Alexandria
Refer to this link for more information.Tuesday, July 18, 2023
Demystifying Partial Classes in Delphi
Understanding Partial Classes
Splitting Responsibilities
Collaboration and Teamwork
Code Reusability:
Enhanced Maintainability:
Limitations:
Does Delphi support partial classes?
But!
Actually, there is something in Delphi (coming from the Pascal age) that is called include, TMyClass = partial class
procedure P1(AValue: string);
procedure P2;
end;
procedure TMyClass.P1(AValue: string);
begin
{$I External.inc}
end;
procedure TMyClass.P2;
begin
ShowMessage('P2');
end;
How does the "TMyClass.P1" method work?The answer is hidden in another file which is literally a text file and could be with any extension!
In my case, there is one line in this file without respecting the Pascal structure.
ShowMessage(AValue);
I hope this wonderful feature will be added to Delphi soon.
Thursday, July 13, 2023
ChatGPTWizard! a ChatGPT plug-in for Embarcadero RAD Studio.
- Free text question form.
- Dockable question form.
- Inline questions(in the editor).
- Context menu options to help you to find bugs, write tests, optimize code, add comments, etc...
- Class view(Code conversion, code optimizing, test units, and other options per class).
- Predefined Questions for class view.
- History to save your tokens on OpenAI !
- Fuzzy string match searches in the history.
- Animated letters(Like the website).
- AI Code Translator
- Proxy server options.
- Supports Writesonic AI as the second AI service.
- Supports YouChat AI as the third AI service.
Remarks
- It's compatible with Delphi 10.1 Berlin and later versions.
- Uses XSuperObject library which is included in the project files. you can also find the latest version here
- Settings are stored in registry which can be found here: Computer\HKEY_CURRENT_USER\Software\ChatGPTWizard
How to Use
Where to find it?
Have a look at the repository's readme on GitHub for more info.
TMyObject = object !!😲
Yes sir!
There was an old object in TurPascal that was called `Object`!
In Turbo Pascal, the Object type is a base object type that does not require explicit memory management like classes.program ObjectDemo;
type
TMyObject = object
Value: Integer;
procedure Initialize(AValue: Integer);
procedure Display;
end;
procedure TMyObject.Initialize(AValue: Integer);
begin
Value := AValue;
end;
procedure TMyObject.Display;
begin
Writeln('Value:', Value);
end;
var
MyObject: TMyObject;
begin
MyObject.Initialize(42);
MyObject.Display;
// No need to free the object explicitly
Readln;
end.
The Initialize method sets the value of `Value` based on the provided parameter. The `Display` method prints the value of `Value` to the console.
Inside the `begin` and `end` block, we declare a variable `MyObject` of type `TMyObject`. We then call the `Initialize` method on `MyObject` to set its value to 42 and call the `Display` method to print the value to the console.
Since `TMyObject` is an object, it does not require explicit memory management. The object is automatically allocated and deallocated when it goes out of scope.
Note that the `object` type in Turbo Pascal does not support inheritance or virtual methods like classes do. It is a simpler construct primarily used for encapsulating data and methods within a single unit of code.
Is it available yet in modern Delphi?
Yes, there is, in the matter of backward compatibility.
Implementing Interfaces by Delegation in Delphi!
Implementing Interfaces by Delegation
Is it possible at all?😮
The implements directive allows you to delegate the implementation of an interface to a property in the implementing class. For example:
property MyInterface: IMyInterface read FMyInterface implements IMyInterface;
Declares a property called MyInterface that implements the interface IMyInterface.The implements directive must be the last specifier in the property declaration and can list more than one interface, separated by commas. The delegate property:
- Must be of a class or interface type.
- Cannot be an array property or have an index specifier.
- Must have a read specifier. If the property uses a read method, that method must use the default register calling convention and cannot be dynamic (though it can be virtual) or specify the message directive.
The class you use to implement the delegated interface should derive from System.TAggregatedObject
.
Delegating to an Interface-Type Property
type
IMyInterface = interface
procedure P1;
procedure P2;
end;
TMyClass = class(TObject, IMyInterface)
FMyInterface: IMyInterface;
property MyInterface: IMyInterface read FMyInterface implements IMyInterface;
end;
var
MyClass: TMyClass;
MyInterface: IMyInterface;
begin
MyClass := TMyClass.Create;
MyClass.FMyInterface := ...// some object whose class implements IMyInterface
MyInterface := MyClass;
MyInterface.P1;
end;
Delegating to a Class-Type Property
type
IMyInterface = interface
procedure P1;
procedure P2;
end;
TMyImplClass = class
procedure P1;
procedure P2;
end;
TExternalClass = class(TInterfacedObject, IMyInterface)
private
FMyImplClass: TMyImplClass;
public
procedure IMyInterface.P1 = MyP1AlternativeProcedure;
procedure MyP1AlternativeProcedure;
property MyImplClass: TMyImplClass read FMyImplClass implements IMyInterface;
end;
procedure TMyImplClass.P1;
begin
Writeln('P1 called!');
end;
procedure TMyImplClass.P2;
begin
Writeln('P2 called!');
end;
procedure TExternalClass.MyP1AlternativeProcedure;
begin
Writeln('MyP1AlternativeProcedure called!');
end;
var
LvMyExternalClass: TMyClass;
LvMyInterface: IMyInterface;
begin
LvMyExternalClass := TExternalClass.Create;
LvMyExternalClass.FMyImplClass := TMyImplClass.Create;
LvMyInterface := LvMyExternalClass;
LvMyInterface.P1; // calls TMyClass.MyP1AlternativeProcedure;
LvMyInterface.P2; // calls TImplClass.P2;
Readln;
end;
You can remove the following lines from TExternalClass and it's still implementing the interface correctly and compilable!
procedure IMyInterface.P1 = MyP1AlternativeProcedure;
procedure MyP1AlternativeProcedure; // and its implementation!
Here is another console-type application sample to make it more clear:
program InterfaceDelegationDemo; {$APPTYPE CONSOLE} uses SysUtils; type // Interface definition IFirstInterface = interface procedure FirstMethod; end; ISecondInterface = interface procedure SecondMethod; end; // Implementation of the first interface TFirstInterfaceImplementation = class(TInterfacedObject, IFirstInterface) procedure FirstMethod; end; // Implementation of the second interface using delegation TSecondInterfaceImplementation = class(TInterfacedObject, ISecondInterface) private FFirstInterfaceImpl: IFirstInterface; public constructor Create(AFirstInterfaceImpl: IFirstInterface); procedure SecondMethod; end; { TFirstInterfaceImplementation } procedure TFirstInterfaceImplementation.FirstMethod; begin Writeln('FirstMethod called'); end; { TSecondInterfaceImplementation } constructor TSecondInterfaceImplementation.Create(AFirstInterfaceImpl: IFirstInterface); begin FFirstInterfaceImpl := AFirstInterfaceImpl; end; procedure TSecondInterfaceImplementation.SecondMethod; begin Writeln('SecondMethod called'); FFirstInterfaceImpl.FirstMethod; // Delegating the method call to the first interface implementation end; var FirstInterfaceImpl: IFirstInterface; SecondInterfaceImpl: ISecondInterface; begin FirstInterfaceImpl := TFirstInterfaceImplementation.Create; SecondInterfaceImpl := TSecondInterfaceImplementation.Create(FirstInterfaceImpl); SecondInterfaceImpl.SecondMethod; Readln; end.
The TSecondInterfaceImplementation class takes an instance of IFirstInterface as a constructor parameter, which represents the first interface implementation. It stores this instance in the FFirstInterfaceImpl field.
When the SecondMethod of TSecondInterfaceImplementation is called, it first prints a message indicating that the method has been called. Then, it delegates the method call to the FirstMethod of the first interface implementation by calling FFirstInterfaceImpl.FirstMethod.
By using this delegation approach, you can separate the implementation of each interface and reuse existing implementations by passing them as parameters to other interface implementations.
Wednesday, July 12, 2023
The fastest compiler of any programming language ever!
The fastest compiler of any programming language ever is a matter of debate, but some of the contenders include:
- Turbo Pascal. This compiler was released in 1983 and was known for its speed. It could compile a Pascal program in a fraction of a second, which was very impressive at the time.
- WATFOR, WATFIV, and WATBOL. These compilers were developed in the 1960s and 1970s for educational purposes. They were designed to be very fast, so that students could get their programs compiled and running quickly.
- Jon Blow's Jai. This language is still under development, but it has the potential to be one of the fastest compilers ever. Jai is designed to be very efficient and to produce high-performance code.
What about the modern Pascal (Delphi) compiler?
Delphi is one of the fastest compilers of all time. this means that Delphi can compile code faster than a lot of other compilers. this is due to the fact that Delphi uses a technology called "incremental compilation." Incremental compilation means that Delphi only compiles the parts of the code that have been changed since the last compilation. This saves a lot of time when compiling large projects. Delphi also has an optimizer that can perform various optimizations to the code. This results in faster running code.
Delphi also has a feature called "link time optimization." Link time optimization means that Delphi can optimize the code even more by analyzing the whole project at once. This is different from other compilers that optimize each unit separately. The result is even faster and more efficient code.
Moreover, Delphi has a great community that constantly provides support, tools, and libraries. There are many different libraries available for Delphi that can be used to speed up development and improve the performance of code.
Another advantage of using Delphi is that it supports multiple platforms, including Windows, macOS, iOS, and Android. This means that developers can create applications for various platforms using the same codebase with Delphi.
P.S : In summary, Delphi is the fastest compiler of any programming language that I've tried until now, I tried C, Java, and C# during my career time and recently Dart!
Due to its incremental compilation feature, optimizer, and link time optimization. Additionally, the wide range of support provided by the community and the multi-platform capabilities make it a great choice for developers looking to create efficient and effective applications.