Hack 52. Generate Code with Macros
Use macros to help generate repetitious
sections of code.
Often you will find that you have blocks
of code in a project that are virtually identical. Generating this
code using a macro has the advantages of ensuring the code is the
same in each location and saving valuable developer time.
6.10.1. Creating a Simple Generation Macro
Suppose you want to create a function for each value in an
enumeration. Code generation is useful for creating an initial set of
functions and can be done using a more typical generation tool such
as CodeSmith [Hack #50] . However, often
you will find that after hand-editing some of the generated
functions, the prospect of regenerating the entire set is undesirable
when all you wish to do is add a single function. At the same time,
for more complex examples, copy-pasting an existing example may
result in a lot of editing. Using a macro to generate a single
example gives you another option for cases in which you know there
will be edits later.
6.10.1.1 Recording a code template
The simplest way to create a macro to generate repetitive blocks of
code is to use the macro recorder to record the creation of one
of the blocks, and then edit the macro to parameterize it. Open the
file you wish to create the function in and start the macro recorder
[Hack #51] . Create the
function as you normally would, then stop the macro recorder.
|
For VB.NET users, it is important to turn off the
"Automatic insertion of end
constructs" option before both recording and playing
back your macro. This option can be configured through Tools
Options Text Editor Basic
VB Specific. Otherwise, your macro will insert multiple end
constructs (such as End If).
|
|
Here is a sample of a recorded macro:
Sub TemporaryMacro( )
DTE.ActiveDocument.Selection.NewLine( )
DTE.ActiveDocument.Selection.Text = _
"private void RecordFoo( Enum.Foo value )"
DTE.ActiveDocument.Selection.NewLine( )
DTE.ActiveDocument.Selection.Text = "{"
DTE.ActiveDocument.Selection.NewLine( )
DTE.ActiveDocument.Selection.Text = _
"BusinessLogicCall.RecordEnum( value, OurEnum.Foo ) ;"
DTE.ActiveDocument.Selection.NewLine( )
DTE.ActiveDocument.Selection.Text = "}"
End Sub
6.10.1.2 Generalizing the macro
After recording the macro, open the macro editor. You can now
parameterize your macro by changing the variable portions of your
function with variables and reading the desired settings either from
the environment or with InputBox functions that allow the user to
enter simple data. I have changed the function name from
TemporaryMacro to Macro1 so it
will not be lost if I record another macro.
Sub Macro1( )
Dim var As String = InputBox("Enter enum name")
DTE.ActiveDocument.Selection.NewLine( )
DTE.ActiveDocument.Selection.Text = _
"private void Record" + var + "( int value )"
DTE.ActiveDocument.Selection.NewLine( )
DTE.ActiveDocument.Selection.Text = "{"
DTE.ActiveDocument.Selection.NewLine( )
DTE.ActiveDocument.Selection.Text = _
"BusinessLogicCall.RecordEnum( value, OurEnum." + var + " ) ;"
DTE.ActiveDocument.Selection.NewLine( )
DTE.ActiveDocument.Selection.Text = "}"
End Sub
6.10.1.3 Resulting code
In this example, you now have a macro
that is useful for generating new versions of the Record function
when new items are added to the OurEnum
enumeration. This can be useful when providing a Business Layer
interface in which you wish to provide a distinct function for each
value of the enumeration.
If you type NewValue into the InputBox prompt,
the macro will create the following function:
private void RecordNewValue( int value )
{
BusinessLogicCall.RecordEnum( value, Enum.NewValue ) ;
}
�Ben Von Handorf
|
No comments:
Post a Comment