Refactoring Procedure Signatures: The Do's and Don'ts

Best practices for modifying procedure signatures while maintaining backward compatibility.

Refactoring Procedure Signatures: The Do's and Don'ts

As our VBA code evolves, we often need to modify existing procedure signatures.

What is a Procedure Signature?
The concept of procedure signatures explained in under 100 words. #Under100

However, it's crucial to understand the potential risks and follow best practices to maintain backward compatibility.

Understanding the Risks of Modifying Procedure Signatures

Changing procedure signatures can break existing code that calls those procedures.

When modifying a signature, consider the impact on any code that currently calls the procedure. This includes code in the same project, as well as any other projects where it may be reused. Be especially cautious when modifying procedures in a shared code library file, as the impact can be far-reaching.

Building Your Library
Thirteen years ago, I chose to maintain a folder of text files rather than a single Access database library. I’ve never once regretted that decision.

Careless changes can lead to compile errors, runtime errors, or even subtle logic bugs.

When It's Appropriate to Modify a Procedure Signature

There are times when modifying a procedure signature is necessary or beneficial.

Some valid reasons to modify a signature include:

  • Adding new functionality
  • Improving code readability
  • Making a procedure more generic

For example, if a procedure has a hard-coded value that limits its reusability, you can make the procedure more generic by extracting that value into a new optional parameter. This allows the procedure to support more scenarios without breaking existing code that relies on the original behavior.

Adding Procedure Parameters Without Breaking Backwards Compatibility in VBA
Sometimes you need to add a parameter to a Function or Sub in VBA. But you don’t need to break all of your calling code to do it.

Best Practices for Changing Parameter Types

When changing a parameter type, it's generally safer to make the new type more accommodating than the old type.

For example, changing from a specific type like Integer to a more general type like Variant is usually safe (though you sacrifice some compile-time safety checks as a result).

Avoid changing parameter types in a way that would require calling code to be modified. For instance, don't change a parameter from a String to an object type, as that would require updates to any code that passes a string literal.

How to Safely Expand Procedure Visibility and Scope

If you need to make a procedure more widely accessible, it's safe to expand its visibility or scope. For example, you can change a Private procedure to Public, or a Friend procedure to Public.

However, avoid restricting a procedure's visibility or scope, as that can break existing code that relies on the current accessibility. For instance, don't change a Public procedure to Private if it's used by other modules.

Scope vs. Extent in VBA
Master the extent and scope of your VBA variables for code that’s efficient, effective, and easy to maintain.

Guidelines for Adding Optional Parameters

When adding new parameters to a procedure, it's important to make them optional and place them at the end of the parameter list. This allows existing code to continue calling the procedure without providing the new parameters.

Remember, if the new optional parameter is replacing a hard-coded value from the procedure, be sure to set its default value to match the one that was previously hard-coded.

Considerations When Renaming Parameters

Renaming parameters can improve code readability, but it comes with risks.

Calling code that uses the named parameter syntax (argumentName:=value) will break if the parameter name changes.

Before renaming a parameter, search your codebase to ensure the named parameter syntax isn't used. If it is, you'll need to carefully update all the affected code. Tools like MZ-Tools can help with this (the Method Callers feature is great for this).

Techniques for Searching and Updating Existing Code

When you do need to make breaking changes to a procedure signature, it's crucial to find and update all the code that calls the procedure.

Use the built-in VBIDE search feature if you must, but I prefer a third-party tool, such as:

Don't rely solely on compile errors to identify affected code. Some changes, like renamed parameters, can silently introduce logic bugs without causing compile errors. Thoroughly test the calling code after making signature modifications.

Exceptions to the Rules - When Breaking Changes May Be Warranted

While it's generally best to avoid breaking changes, there are situations where they may be justified.

If a procedure is used only within a single project and you can easily update all the calling code, a breaking change may be acceptable.

Breaking changes may also be necessary when fixing critical bugs or security vulnerabilities. In these cases, the benefits of the change outweigh the costs of updating the calling code.

When you do make a breaking change, clearly document it and communicate with any other developers who may be impacted.

By understanding these principles and following best practices, you can safely evolve your VBA procedure signatures while minimizing the risk of breaking existing code. Careful planning and attention to detail are key to maintaining backward compatibility.

Acknowledgements
  • Initial draft generated with the help of Claude-3-Opus
  • Cover image generated by DALL-E-3
  • Cover image created with Microsoft Designer

All original code samples by Mike Wolfe are licensed under CC BY 4.0