ddablib / envvars

Environment Variables Unit
1 stars 2 forks source link

Add templated enumerator methods & callbacks to TPJEnvironmentVars #6

Closed delphidabbler closed 2 years ago

delphidabbler commented 2 years ago

At present there are two enumerator methods of TPJEnvironmentVars:

class procedure EnumNames(Callback: TPJEnvVarsEnum; Data: Pointer);
class procedure EnumVars(Callback: TPJEnvVarsEnumEx; Data: Pointer);

As can be seen these enumerators are passed data in the traditional way, as a pointer. Often the pointer would be cast to an object on an integer, which isn't type safe.

How about adding some templated overloaded methods like these:

class procedure EnumNames<T>(Callback: TPJEnvVarsEnum<T>; Data: T);
class procedure EnumVars<T>(Callback: TPJEnvVarsEnumEx<T>; Data: T);

We will need new enumerator types:

TPJEnvVarsEnum<T> =  reference to procedure(const VarName: string; Data: T);
TPJEnvVarsEnum<T> =  reference to procedure(const EnvVar: TPJEnvironmentVar; Data: T);

The original methods and callback types could be deprecated.

delphidabbler commented 2 years ago

See also issue #7 about moving callback type definitions into TPJEnvironmentVars class definition. If that is done, the names and definitions of the types & methods proposed here would change as follows:

type
  TPJEnvironmentVars = class(TObject)
  // ...
  public
    type
      TEnumNamesCallback<T> = reference to procedure(const VarName: string; Data: T);
      TEnumVarsCallback<T> = reference to procedure(const EnvVar: TPJEnvironmentVar; Data: T);
      // TEnumNamesCallback = reference to procedure(const VarName: string; Data: Pointer);
      // TEnumVarsCallback = reference to procedure(const EnvVar: TPJEnvironmentVar; Data: Pointer);
    // ...
    class procedure EnumNames<T>(Callback: TEnumNamesCallback<T>; Data: T); overload;
    class procedure EnumVars<T>(Callback: TEnumVarsCallback<T>; Data: T); overload;
    class procedure EnumNames(Callback: TEnumNamesCallback<Pointer>; Data: Pointer); overload;
      deprecated 'Use TPJEnvironmentVars.EnumNames<Pointer> instead';
    class procedure EnumVars(Callback: TEnumVarsCallback<Pointer>; Data: Pointer); overload;
      deprecated 'Use TPJEnvironmentVars.EnumVars<Pointer> instead';
  end;

Note that TEnumNamesCallback & TEnumVarsCallback proposed in issue #7 would no longer be required because the types are equivalent to TEnumNamesCallback<Pointer> & TEnumVarsCallback<Pointer> respectively. The types have been commented out above for that reason.

The definitions of TPJEnvVarsEnum and TPJEnvVarsEnumEx in issue #7 now become:

type
  TPJEnvVarsEnum = TPJEnvironmentVars.TEnumNamesCallback<Pointer>
    deprecated 'Use TPJEnvironmentVars.TEnumNamesCallback<Pointer> instead';
  TPJEnvVarsEnumEx = TPJEnvironmentVars.TEnumVarsCallback<Pointer>
    deprecated 'Use TPJEnvironmentVars.TEnumVarsCallback<Pointer> instead';
delphidabbler commented 2 years ago

The implementation of TPJEnvironmentVars.EnumNames should be copied into TPJEnvironmentVars.EnumNames<T> and TPJEnvironmentVars.EnumNames should be changed to call TPJEnvironmentVars.EnumNames<Pointer>.

Similarly for TPJEnvironmentVars.EnumVars and TPJEnvironmentVars.EnumVars<T>.