[AccessD] Class Rebuttal was: Basic Unbound Form ...

Heenan, Lambert Lambert.Heenan at AIG.com
Mon Jun 12 16:16:20 CDT 2006


Hello Drew (and anyone else following along in the discussion - feel free to
chime in),

'Next, "but globals are bad news in any context", not this again.  Public
variables are not BUGGY, nor are they 'bad news'.  They have a purpose, that
is why they are there in the first place' .

Sorry , can't agree with that either. Public variables are there so that
code written for ancient systems, running languages that had only one kind
of variable - public ones - can continue to be run. It's a backward
compatibility feature. I know that may seem like a bold, overarching
statement, but look at the history of programming languages. Why was the
concept of 'local variables' dreamt up? Because having all global variables
was a nightmare The fact that lots people (myself included!) have a tendency
to cut corners and use them as a quick and dirty way to get data moving from
one module to another does not mean that it's a good idea.  There's really
no excuse for using a global, as rewriting the code to use local variables
requires very little effort.

Likewise, writing a few lines of code to implement a very simple Let/Get
pair of properties is not difficult. But the benefits are that you know
exactly how and where your class' data is being changed. If you pepper your
classes with public members fields then you have simply throws away 50% of
the reasons for using classes. If you think that code is better because it
uses less lines, or characters or pixels on screen, dots on paper or
electrons moving though wires, then you are simply mistaken. I'd rather
spend my time writing the few extra lines of code that the extra time needed
to debug it when it behaves oddly. My argument against the use of globals is
not based on the peculiarities of VB ("they lose their values" [if a runtime
error is not trapped]) it's based on the idea that a global, by its very
nature can be modified from almost anywhere at all in code, and that  makes
for a debug/maintenance problem.

So if I were teaching someone some VERY basic code, like how to calculate
the cube of an integer I COULD write this...

Dim nNumber as Long

Sub TryItOut
     nNumber = 7
     Debug.Print "The cube of " & nNumber & " is " & nNumber^3 
End Sub

.. Which illustrates how variables are assigned values, how to use the
'power' operator and the concept of outputting results for debugging.

However I would probably write...

Function nCube(nNumber as Long) as Long
	nCube = nNumber^3
End Function

Sub TryItOut
Dim nLocalNumber as Long
     nLocalNumber = 7
     Debug.Print "The cube of " & nLocalNumber & " is " & nCube(nLocalNumber
) 
End Sub

Both examples do the job, but the latter version, at the cost of writing
some more code, illustrates the concepts of local variables, parameter
passing, functions calling and function return values. All essential to
ordinary day-to-day programming. 

Regarding your error class example. "Both routines cause the same error, and
stop at the same point.  The SecondValue error NEVER reaches the
ErrorHandler!!!  If a property of a class is going to do NOTHING but hold a
value, the only error you can get involving the use of that value is going
to fall into the domain of the calling code.  If you are setting an invalid
value, i.e., wrong type, too big, etc, the error is going to occur in the
code trying to set the value.  Quite frankly, putting error handling in a
property get/let combo above is pointless, it will never be used (unless it
was just simply written wrong)."  What you say here is perfectly valid for
the example given, but it is also language specific. VB behaves just as you
say, but a less strongly typed language will not. 

But even keeping the discussion within the domain of VB, sure you get a type
error when you try to pass a string to a routine that wants an integer, so
the class property error handler is not involved, but what about passing an
integer that's outside the acceptable range to a routine that wants an
integer? If MyValue is only allowed to take on values in one (or more)
specific ranges, then you'd better be sure that it keeps within those
bounds, and that's exactly what a property Let method can take care of.

I guess what my point of view boils down to is that it's perfectly ok to
teach programming concepts in itty bitty pieces, but the examples used
should be sufficiently complex to illustrate why the technique being used
*is being used*. That little bit of complexity can make the example seem
more realistic. By building your first class with Let and Get properties the
concepts of data hiding and access control methods are introduced early on,
which is a good thing. After the beginner has "learned the rules" the notion
of what might be gained and lost by bending the rules will make more sense.

Lambert

-----Original Message-----
From: accessd-bounces at databaseadvisors.com
[mailto:accessd-bounces at databaseadvisors.com] On Behalf Of DWUTKA at marlow.com
Sent: Monday, June 12, 2006 3:11 PM
To: accessd at databaseadvisors.com
Subject: [AccessD] Class Rebuttal was: Basic Unbound Form ...


Well Lambert, I'm glad you didn't write the MSDN, because if I had to wade
through this kind of logic to learn what I have, I would probably go back to
being a mechanic.

First of all, "But not as much of a waste of time as the process of
explaining later on why public members fields have drawbacks.", they don't
have drawbacks, they have limitations, which I explained.  I made it very
obvious that a Public declaration is the same as a BASIC Get/Let statement.
BASIC!!!!  You can't put logic into a Public declaration, but you can with a
Get/Let statement, which would no longer be a 'BASIC' Get/Let statement.

Next, "but globals are bad news in any context", not this again.  Public
variables are not BUGGY, nor are they 'bad news'.  They have a purpose, that
is why they are there in the first place.  The are things that you can do
with a public variable that are simply nightmares to try and do without.  In
the advanced demo, I will show a method of public declaration which I'd LOVE
to see you duplicate in another manner.

As far as data encapsulation, look, if you build every class to go far
beyond what you need it for, you're wasting time.  I have a pretty flexible
job, but even I don't over-program that much.  If all you need is a place
holder for a value, then just put a place holder for the value.  Not a lot
of lines, eh?  Let's look at that.

Public MyValue as Long 

That's one line.

Dim lngMyValue as Long
Property Get MyValue() as Long
MyValue=lngMyValue
End Property
Property Let MyValue(lngEnter As Long)
lngMyValue=lngEnter
End Property

That would be 7 lines.  Seven times the amount of code.  It's also 22
characters compared to 151 characters, which is still roughly 7 times more.
For one property, great, you spend 21 seconds to create a property rather
then 3 seconds.  But now create a class that has 50 properties, non of which
require any extra work done to them.  Now instead of spending 2 and half
minutes creating your class, you are going to spend 17 and a half minutes.
It adds up.

Now for this one: "It's a "property" of sorts, but more than that it's a
gaping hole in a class definition that invites unintended side-effect, aka
'bugs'."

Would you like to clarify that one for me?  I'd just love to see what
'unintended side-effect that you get from my above example.  Both will do
the EXACT same thing.  Even in an error situation.  Here's a 'TestError'
class.

Property Let SecondValue(intEnter As Long)
On Error GoTo Errorhandler
intSecond = intEnter
Exit Property

Errorhandler:
Err.Clear
MsgBox "We got an error!"
End Property

Now let's test that out:

Private Sub Command0_Click()
Dim te As testerror
Set te = New testerror
te.FirstValue = "One"
End Sub

Private Sub Command1_Click()
Dim te As testerror
Set te = New testerror
te.SecondValue = "One"
End Sub

Both routines cause the same error, and stop at the same point.  The
SecondValue error NEVER reaches the ErrorHandler!!!  If a property of a
class is going to do NOTHING but hold a value, the only error you can get
involving the use of that value is going to fall into the domain of the
calling code.  If you are setting an invalid value, ie, wrong type, too big,
etc, the error is going to occur in the code trying to set the value.  Quite
frankly, putting errorhandling in a property get/let combo above is
pointless, it will never be used (unless it was just simply written wrong).

So if you would like to argue this more, show me one SOLID difference
between the two dealing with performance or operability.  Saying that it's
'bad practice' is bull pucky, and saying that it 'leads to bugs' is even
MORE bull pucky!

I know a lot of this sounds like a rant, and some of it is.  But I was asked
to demonstrate how to create an unbound form using classes.  I have taught
before, and when you are teaching a complex subject, you take it one step at
a time.  You also put into what you teach what you have discovered on your
own, and you try VERY hard to not prejudice your material too much.  If you
include a prejudice, you explain the facts, but let the student make their
own decisions.  That is why I defend a few things on this list that several
members disagree with.  I defend them because they are prejudices. Several
list members have presented 'bad practice' items which are based on personal
and prejudiced experience or tribal knowledge.  THAT is bad practice.  You
have to keep in mind that the list is a mix of members.  We would NEVER have
had this particular thread offshoot if the list was made up of only expert
programmers, because no one would have asked for such a demonstration.  

For example, the 'global variables are bad practice' thing.  They are not
bad practice.  The arguments thrown up for them are either false, or
misrepresented.  For example the 'they can lose their value'.  That is a mix
of both.  That particular argument is based on a trait of VBA, which any
serious developer whould be well aware off, and that is that an unhandled
error can provide a prompt to the user which will STOP the currently running
code, which not only stops the current process, but it will release all
memory resident values (including Global Variables).  In Visual Basic, End
closes everything up.  In Access (or Word/Excel/etc.), End simply stops the
VBA process, but the parent program is still running.

Drew

-----Original Message-----
From: Heenan, Lambert [mailto:Lambert.Heenan at aig.com]
Sent: Monday, June 12, 2006 12:48 PM
To: 'Access Developers discussion and problem solving'
Subject: Re: [AccessD] Basic Unbound Form with Classes and Collections Par
t1.


" Putting in Get and Let statements, with a class level module dimensioned
would actually just be wasted lines of code in this demo project."

... But not as much of a waste of time as the process of explaining later on
why public members fields have drawbacks. That they cause problems that the
whole OOP methodology was designed to eliminate. In short, why try to teach
the use of classes by beginning with an example which is bad programming.
I'm sorry to have to contradict you there, but globals are bad news in any
context, and they are especially bad when they negate the major advantage of
using a class - data encapsulation, one of the  two main reasons to use
classes, the other being simplified code reuse.

Especially in VB/VBA, a public member declaration looks exactly the same as
a public variable declaration in a standard module. By using this as an
example of a class the newbie is then faces with the puzzle of why there are
different syntaxes for accessing the data. The answer is "because it's a
class member", but little is learned from this fact.

If instead you go to the trouble of declaring a couple of Get and Let
properties, which will only take a couple of lines each, not thousands of
them, then a much clearer idea of what a property is can be conveyed. "But
you do agree that using Public in a class is essentially a property", well
no. It's a "property" of sorts, but more than that it's a gaping hole in a
class definition that invites unintended side-effect, aka 'bugs'.

Lambert



More information about the AccessD mailing list