Wednesday, November 4, 2009

Hack 52. Generate Code with Macros











 < Day Day Up > 





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





















     < Day Day Up > 



    No comments:

    Post a Comment