Function structure

Its quite common to require opposite pairs of functionality. Things like show/hide, or hide/unhide, or protect/unprotect, register/unregister, load/unload… you get the idea.

There are 2 basic approaches to this:

  1. have 1 function that takes a true/false parameter to tell it to do or undo the action
  2. have 2 clearly named functions whose names are good opposites, as above.

Which do you prefer?

I personally prefer the 2nd (I think) and I would say thats usually the way we interact with COM object models. I notice a lot of C code and Win API stuff uses the first though, so I thought about it a bit more.

I think the second (2 separate methods) is probably easier to understand, but on reflection the first is maybe more powerful. Or at least allows more concise code.


if msgb = vbyes then
end if

to the more concise = vbyes)

I guess the hard bit is getting a method name that makes sense with a true false parameter. Maybe a property gives the best of both worlds?

menu.visible = (msgb = vbyes)

What do you prefer? in your own code? in working with others (eg libraries)?




11 Responses to “Function structure”

  1. Harlan Grove Says:

    Guess you hit on the big question: should your example be a method or property? If method, then two separate methods would be better. If property, then one property taking a boolean argument would be better. So, should displaying or hiding a menu be an action (thus done using methods) or should this be considered a change of state (thus done changing a property)?

    Do you drive on the left side of the road or the right?

  2. Dick Kusleika Says:

    When ever I write a procedure in a userform to enable/disable buttons based on context, I ask myself this same question. Should I write an enable procedure and a disable procedure so the code is clear and easy to understand? Or should I write one procedure? I always end up with one because I don’t want to repeat code (makes editing harder). I try to name my procedure as verb+none (e.g. EnableButtons). I think EnableButtons False is easy to understand.

  3. Stephane Rodriguez Says:

    What’s missing in that picture is the additional isdirty field for each property.

  4. Marcus Says:

    I prefer to toggle option with a single function, partially to reduce the amount and duplication of code.

    However, often there’s circumstances where there are more than one alternative (yes, no, maybe) in which case I usually use an enumerator as a parameter to the method. I’ve seen others pass strings, but I prefer the readability and error control an enum provides (passing anything other than a valid enum value generates an error).

    Cheers – Marcus

  5. Rob Bruce Says:

    It depends on the exact circumstance, but I’d say that is counter-intuitive and should be disregarded: If you’re going to use methods, then you’re going to need a separate one for each purpose i.e.[params]) and menu.hide([params]).

    However, for toggles of state, a property procedure pair is absolutely the way to go, no question in my mind. The only debate, really, is whether show/hide is a simple toggle or something more.

  6. Johan Nordberg Says:

    I would generally go for one method that passes a true/false parameter. If I like to be really clear I would then do something like this:

    Sub ToggleButtons(ByVal bEnable As Boolean)
    ‘ The usual crap
    End Sub

    Sub EnableButtons()
    ToggleButtons True
    End Sub

    Sub DisableButtons()
    ToggleButtons False
    End Sub

    If there are more than true/false I would go for the Enum to get compile time errors and full intellisense in the editor.

    But if it’s just one custom object I think a property is better. I think cmdButton.Enabled = true is better than cmdButton.Enable() or cmdButton.Disable().

  7. Simon Says:

    Harlan being UK based I have the privilege of driving on both sides of the road, left here and right when I visit our neighbours across the channel.

  8. jonpeltier Says:

    I learned to drive in Rhode Island, where it was permissible to drive on both sides of the road. Also in the middle.

    About the question: two procedures or one procedure with an argument, the definitive answer is “it depends”. I’ve gotten into the habit of writing functions instead of subs, so

    Set TheChart = BuildTheChart(CustomType as enum, rngData as Range)

    rather than

    BuildTheChart CustomType as enum, rngData as Range

    I can query whether TheChart Is Nothing to see if the function worked, and I have the object defined so I can do something further with it.

    Johan’s last comment, using dual approaches, is what I do with forms and other classes, where there is a property procedure that accepts an argument, and based on the argument, different sequences of actions are taken.

  9. Marcus Says:

    “…I have the privilege of driving on both sides of the road…”

    I was guessing that that was your natural driving style (regardess of intoxication level).

    When in australia, of course, we drive upside down.

    Cheers – Marcus

  10. Stephen Bullen Says:

    Like Harlan, if a procedure *does* something, I use a Sub or Function, name it with a verb and have an equivalent verb for the opposite action. If procedure just changes state, I use a Property procedure, named with an adjective describing the thing being changed. And it’s a judgement call which to use. I’ve seen code using any (or all) of the following:
    RunReport = “Go”
    cmdDoIt.Value = True

    Where the latter is used the ‘click’ a button on a form!

  11. Ross Says:

    All things beging equal, which they are not of course, I like using 2 functions, so there! ;-)

Leave a Reply

Please log in using one of these methods to post your comment: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: