By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,028 Members | 1,733 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,028 IT Pros & Developers. It's quick & easy.

Why to be careful declaring variable As New ...

P: n/a
Many of the regulars here have explained that declaring variables using As New
.... is a bad idea, and some have given some good explanations, but I wanted
add one more demonstration to the mix. This example is less practical than
some, but more illustrative than most. I came up with this to show a fellow
programmer why I think he's using As New ... too much, and I though I might as
well share it here, too.

First create a class as follows...

- clsInitTerminateChecker -
Option Compare Database
Option Explicit

Private Sub Class_Initialize()
Debug.Print " - Initialize -"
End Sub

Private Sub Class_Terminate()
Debug.Print " - Terminate -"
End Sub
Now create a standard module, and add the following procedure...

Public Sub TestAsNewInitTerminate()
Dim objInitTerminateChecker As New clsInitTerminateChecker

Debug.Print "Start of procedure"
Debug.Print " Now check for Nothing"
Debug.Print " Is Nothing: " & (objInitTerminateChecker Is Nothing)
Debug.Print " Now set to Nothing"
Set objInitTerminateChecker = Nothing
Debug.Print " Now check again for Nothing"
Debug.Print " Is Nothing: " & (objInitTerminateChecker Is Nothing)
Debug.Print "End of procedure"

End Sub

Run it, and you get the following output...

Start of procedure
Now check for Nothing
- Initialize -
Is Nothing: False
Now set to Nothing
- Terminate -
Now check again for Nothing
- Initialize -
Is Nothing: False
End of procedure
- Terminate -

Note that you can't use Is Nothing either to determine whether the object has
been initialized, since it will always be initialized before it is referenced
in any expression including <obj> Is Nothing. Checking for Nothing is a
useful technique for determining whether an object variable must be
initialized before it can be used, and full initialization almost always
requires more than just creating a new object.

Note that this is caveat only applies to classic VB/VBA and not to true OOP
languages like VB.NET, C#, or Java. That's because, in those languages, New
simply means to initialize the object at the point the variable is declared,
and it allows arguments to be passed to a constructor for full, immediate
intitialization. In VB/VBA, the New keyword actually means that VB should
check the variable each time it is referred to, and set it to a new instance
of its object type if it is not already set, and any data that must be passed
to the nex instance must be done after the fact.
Nov 12 '05 #1
Share this Question
Share on Google+
6 Replies


P: n/a
Steve Jorgensen <no****@nospam.nospam> wrote in
news:55********************************@4ax.com:
Many of the regulars here have explained that declaring variables
using As New ... is a bad idea, and some have given some good
explanations, but I wanted add one more demonstration to the mix.
This example is less practical than some, but more illustrative
than most. I came up with this to show a fellow programmer why I
think he's using As New ... too much, and I though I might as well
share it here, too.

First create a class as follows...

- clsInitTerminateChecker -
Option Compare Database
Option Explicit

Private Sub Class_Initialize()
Debug.Print " - Initialize -"
End Sub

Private Sub Class_Terminate()
Debug.Print " - Terminate -"
End Sub
Now create a standard module, and add the following procedure...

Public Sub TestAsNewInitTerminate()
Dim objInitTerminateChecker As New clsInitTerminateChecker

Debug.Print "Start of procedure"
Debug.Print " Now check for Nothing"
Debug.Print " Is Nothing: " & (objInitTerminateChecker Is
Nothing) Debug.Print " Now set to Nothing"
Set objInitTerminateChecker = Nothing
Debug.Print " Now check again for Nothing"
Debug.Print " Is Nothing: " & (objInitTerminateChecker Is
Nothing) Debug.Print "End of procedure"

End Sub

Run it, and you get the following output...

Start of procedure
Now check for Nothing
- Initialize -
Is Nothing: False
Now set to Nothing
- Terminate -
Now check again for Nothing
- Initialize -
Is Nothing: False
End of procedure
- Terminate -

Note that you can't use Is Nothing either to determine whether the
object has been initialized, since it will always be initialized
before it is referenced in any expression including <obj> Is
Nothing. Checking for Nothing is a useful technique for
determining whether an object variable must be initialized before
it can be used, and full initialization almost always requires
more than just creating a new object.


But all you've shown is that you don't *need* to check a class
module referred to by a variable name declared with As New ...

That is, any reference to the class module instance referred to by
the variable will *automatically* initialize it.

This looks to me like a feature rather than a drawback.

The only part of managing it that is a problem is the same problem
you have with any globally available data: you don't know exactly
what state of initialization it will be in. That is, it could be a
leftover instance that has old data in it.

But that's an issue regardless. All you have to do is force
initialization in a clean state by setting it to Nothing *before*
then using any of its properties/methods/members.

I just don't see the issue here, Steve.

Your criticism seems to me to come from a mistaken use of testing
for Is Nothing as a way of telling if a structure is initialized
(that's not always reliable, BTW). With class modules referred to by
variables initialized with As New... there is no need to check at
all, since it can never be non-initialized.

--
David W. Fenton http://www.bway.net/~dfenton
dfenton at bway dot net http://www.bway.net/~dfassoc
Nov 12 '05 #2

P: n/a
On Tue, 17 Feb 2004 16:39:56 GMT, "David W. Fenton"
<dX********@bway.net.invalid> wrote:
Steve Jorgensen <no****@nospam.nospam> wrote in
news:55********************************@4ax.com :
....But all you've shown is that you don't *need* to check a class
module referred to by a variable name declared with As New ...

That is, any reference to the class module instance referred to by
the variable will *automatically* initialize it.

This looks to me like a feature rather than a drawback.
Sure, it's a veature, but one that must be used with care - see below.
The only part of managing it that is a problem is the same problem
you have with any globally available data: you don't know exactly
what state of initialization it will be in. That is, it could be a
leftover instance that has old data in it.
No, that's only on half of the problem space. The other half is that
initializing an instance to a usable state generally involves more than
creating a new instance. If you use As New ..., then you can no longer use Is
Nothing to determine either that a) the object requires intitialization (not
just creation) before it can be used, or b) that the object has not been
initialized, and doesn't need to be cleaned up (especially important with
DAO!)
But that's an issue regardless. All you have to do is force
initialization in a clean state by setting it to Nothing *before*
then using any of its properties/methods/members.
If all you need to do is make sure you have a pristine new instance, that's
true. Frequently, that's not the case, and that's when As New ... can get you
into trouble.
I just don't see the issue here, Steve.

Your criticism seems to me to come from a mistaken use of testing
for Is Nothing as a way of telling if a structure is initialized
(that's not always reliable, BTW). With class modules referred to by
variables initialized with As New... there is no need to check at
all, since it can never be non-initialized.


OK, here's a clear example of some problematic type of code I've seen. Notice
that the connection will never be closed!

Sub Foo
Dim cnn As New ADO.Connection
On Error Goto Proc_Error
' ... Do some stuff ...
cnn.ConnectionString = constConnectionString
' ... Do more stuff ...

Exit_Proc:
If not cnn Is Nothing Then
cnn.Close
set cnn = Nothing
End If
Exit Sub

Proc_Error:
MsgBox strErrDescrip
Resume Exit Sub

End Sub
Nov 12 '05 #3

P: n/a
On Tue, 17 Feb 2004 17:45:59 GMT, Steve Jorgensen <no****@nospam.nospam>
wrote:

....
Sure, it's a veature, but one that must be used with care - see below.

....

Ack - that's "feature", of course.
Nov 12 '05 #4

P: n/a
Steve Jorgensen <no****@nospam.nospam> wrote in
news:kd********************************@4ax.com:
On Tue, 17 Feb 2004 16:39:56 GMT, "David W. Fenton"
<dX********@bway.net.invalid> wrote:
Steve Jorgensen <no****@nospam.nospam> wrote in
news:55********************************@4ax.co m:

...
But all you've shown is that you don't *need* to check a class
module referred to by a variable name declared with As New ...

That is, any reference to the class module instance referred to by
the variable will *automatically* initialize it.

This looks to me like a feature rather than a drawback.


Sure, it's a veature, but one that must be used with care - see
below.


Your example that I was responding to was a class module. You very
often want independent instances of it. If you're using only one,
though, you wouldn't use As New... to define it (unless you wanted
the advantage of self-initialization).

I see from below that you are thinking of something other than class
modules, and in the case below, I agree that it's a mistake. But
it's using the wrong method for defining an object variable, as
opposed to something inherently wrong/dangerous with the technique
itself.
The only part of managing it that is a problem is the same problem
you have with any globally available data: you don't know exactly
what state of initialization it will be in. That is, it could be a
leftover instance that has old data in it.


No, that's only on half of the problem space. The other half is
that initializing an instance to a usable state generally involves
more than creating a new instance. If you use As New ..., then
you can no longer use Is Nothing to determine either that a) the
object requires intitialization (not just creation) before it can
be used, or b) that the object has not been initialized, and
doesn't need to be cleaned up (especially important with DAO!)


You don't *need* to know if it needs to be cleaned up, because you
know if it's been used it *does* need it. So, you set it to Nothing
when you need to clean up. That does clear it, and there's nothing
there.
But that's an issue regardless. All you have to do is force
initialization in a clean state by setting it to Nothing *before*
then using any of its properties/methods/members.


If all you need to do is make sure you have a pristine new
instance, that's true. Frequently, that's not the case, and
that's when As New ... can get you into trouble.


I don't get it.
I just don't see the issue here, Steve.

Your criticism seems to me to come from a mistaken use of testing
for Is Nothing as a way of telling if a structure is initialized
(that's not always reliable, BTW). With class modules referred to
by variables initialized with As New... there is no need to check
at all, since it can never be non-initialized.


OK, here's a clear example of some problematic type of code I've
seen. Notice that the connection will never be closed!

Sub Foo
Dim cnn As New ADO.Connection
On Error Goto Proc_Error
' ... Do some stuff ...
cnn.ConnectionString = constConnectionString
' ... Do more stuff ...

Exit_Proc:
If not cnn Is Nothing Then
cnn.Close
set cnn = Nothing
End If
Exit Sub

Proc_Error:
MsgBox strErrDescrip
Resume Exit Sub

End Sub


Ah. I see.

I was thinking in terms of class modules, where you know what's
inside them since you wrote them.

In this case, yes, I can see that it's a bad idea.

But I don't quite see why anyone would use As New... in this case --
it makes no sense to me. It looks completely redundant, a
programming error.

With class modules, though, or forms (i.e., class modules of a
different type), I don't see the problem.

The problem in your example is creating a new instance when all you
want is to set a variable to a data type. That's the error -- it's a
mis-use of As New..., not a flaw in As New...

--
David W. Fenton http://www.bway.net/~dfenton
dfenton at bway dot net http://www.bway.net/~dfassoc
Nov 12 '05 #5

P: n/a
Steve Jorgensen <no****@nospam.nospam> wrote in
news:0k********************************@4ax.com:
On Tue, 17 Feb 2004 17:45:59 GMT, Steve Jorgensen
<no****@nospam.nospam> wrote:

...
Sure, it's a veature, but one that must be used with care - see
below.

...

Ack - that's "feature", of course.


If you read it with a German accent it comes out OK.

--
David W. Fenton http://www.bway.net/~dfenton
dfenton at bway dot net http://www.bway.net/~dfassoc
Nov 12 '05 #6

P: n/a
On Tue, 17 Feb 2004 18:38:32 GMT, "David W. Fenton"
<dX********@bway.net.invalid> wrote:

....
OK, here's a clear example of some problematic type of code I've
seen. Notice that the connection will never be closed!

Sub Foo
Dim cnn As New ADO.Connection
On Error Goto Proc_Error
' ... Do some stuff ...
cnn.ConnectionString = constConnectionString
' ... Do more stuff ...

Exit_Proc:
If not cnn Is Nothing Then
cnn.Close
set cnn = Nothing
End If
Exit Sub

Proc_Error:
MsgBox strErrDescrip
Resume Exit Sub

End Sub


Ah. I see.

I was thinking in terms of class modules, where you know what's
inside them since you wrote them.

In this case, yes, I can see that it's a bad idea.

But I don't quite see why anyone would use As New... in this case --
it makes no sense to me. It looks completely redundant, a
programming error.

With class modules, though, or forms (i.e., class modules of a
different type), I don't see the problem.

The problem in your example is creating a new instance when all you
want is to set a variable to a data type. That's the error -- it's a
mis-use of As New..., not a flaw in As New...


I guess the deal is that it's obvious to more experienced programmerss like
yourself when not to use As New ..., but from the other code I've seen
recently, it's clearly not obvious to all! That's why I thought a bit of
education was in order.
Nov 12 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.