views:

652

answers:

9

I'm supporting/enhancing a web application written in Classic ASP/VBScript. It has been about 10 years since I have used either in a day to day capacity. I just ran across an issue that I would consider a "gotcha" and was wondering if others had similar things that I should learn to be aware of.

My issue:
I had to convert a Column in a SQL Table from float to decimal. It turns out that decimal isn't a type that is really supported (or supported well) in vbscript. So the following code:

Dim var1, var2

var1 = rs("DecimalField1").Value
var2 = rs("DecimalField2").Value

If (var1 <> var2) Then
    'Do Something'
End If

Would blow up with a Type Mismatch error on the line:

If (var1 <> var2) Then

After much searching I found out that:

var1 = CDBL(rs("DecimalField1").Value)
var2 = CDBL(rs("DecimalField2").Value)

resolves the issue. But that didn't seem like an obvious thing and it took me a while to figure out why the heck I was getting a Type Mismatch on that line.

So my question to everyone is, what other little quirks like this have you run across? What are some things within ASP/vbscript that you would think of as "gotchas" that I should be on the lookout for?

A: 

Make sure that you use Set for object references:

 Dim rs : Set rs = CreateObject("ADODB.Recordset");

If you don't you'll either get an invalid variable reference or the default property

 Dim field      : Set field  = rs(0)
 Dim fieldValue : fieldValue = rs(0) 'Same as field.Value
Mark Cidade
A: 

You can leave out parenthesis when passing arguments to functions but only if the function call is the only expression in the statement:

 DoSomething withThisArgument
 Dim result : result = DoSomething(withThisArgument)
 result = DoSomething withThisArgument 'SYNTAX ERROR
Mark Cidade
I can't think of a single situation where I wouldn't just always use parentheses for the function call.
Joel Coehoorn
It's easier to read and write statements that don't have uneccesary parenthese.
Mark Cidade
Your use of the term expression is misleading, a statement isn't an expression. When using a function in an expression parentheses are always needed. I've never seen anyone attempt this mistake and since this gets picked up as a syntax error its hardly a 'Gotcha'
AnthonyWJones
It's not a long-living gotcha, but is a common one that trips up (mostly new) VBScript authors. I didn't say that a statement was an expression. A statement usually contains expressions, though. In the case of "DoSomething arg" it is a statement consisting of one functional-call-expression.
Mark Cidade
If you always want to use parentheses for consistency, you can use the `Call` keyword before function calls that don't use the return value, like `Call DoSomething(withThisArgument)` example above. I've also heard it recommended when preparing to upgrade an ASP app to ASP.NET.
Mike Henry
Your first line doesn't call a function, it calls a method. Functions return things, methods does things. Not the same thing in VBScript, though it is in loads of other languages. When calling functions, you use parentheses, when calling methods you don't.
svinto
If by method, you mean a subroutine, you can treat any function as if it was a subroutine—the return value will simply be ignored.
Mark Cidade
A: 

Automatic variable allocation is probably one of the biggest gotchas.

Dim varA, varB

varA = varA + varV

Oops! What's varV you ask? Well.. I just mistyped B for V and everything still works perfectly.. that must be a good thing!

Except why isn't varB gets added to varA ?? That must be Microsoft's bug!

chakrit
This is true for most dynamic languages. You should always use "Option Explicit"
Mark Cidade
+2  A: 

A common Gotcha when using HTML forms is a mismatch between the CharSet of the form page and the CodePage of the receiving page.

A typical example is where the Form page sets its CodePage to 65001 and the response CharSet to UTF-8. This causes any values entered into the form to be posted back using UTF-8 encoding. The receiving page leaves its CodePage set the System OEM code page such 1252.

Counter intuatively ASP uses the Response.CodePage to determine how the characters in the form post should be interpreted, hence UTF-8 encoding get erroneously accepted as a set ot 1252 characters corrupting the input.

Sometimes this goes undetected because the page responds sets it Reponse.CharSet to UTF-8 but leaves its CodePage unchanged. The result to the user appears good but data entered into the database is corrupt.

My recommendation is Save as UTF-8, use @codepage = 65001 in all pages and always set Response.CharSet to UTF-8. This covers everything.

AnthonyWJones
+5  A: 

Repeat after me: All good VB programmers use "Option Explicit"

It will keep you from accidentally declaring a new variable and using it - thus throwing off whatever you are doing.

Beyond that, it depends on what you're doing.

AnonJr
+3  A: 

Conditionals are a bit unintuitive at times.

For example, when dealing with Nulls: Although True and Null are not equal, the following expression will act like False. In this case it's good to check for Null explicitly using IsNull.

valueIsTrue = True
valueIsNull = Null
If valueIsTrue <> valueIsNull Then ...

Also, unlike some other languages, all parts of a condition are evaluated even if the first part is False. For example, the following example would return an error if myObject were Nothing:

If Not IsNothing(myObject) And myObject.IsValid() Then ...

The solution is to separate the conditions using nested Ifs or some other means:

If Not IsNothing(myObject) Then
    If myObject.IsValid() Then
        ...
Mike Henry
+4  A: 

Beware anytime you see the following line:

On Error Resume Next

That would be my caution in using classic ASP.

JB King
No doubt these programmers have moved on to silently eating all exceptions.
SqlACID
Of course, there is nothing like those empty catch blocks to prevent errors from showing up. ;)
JB King
A: 

VBScript has a nastly way of letting you call subs with parenthesis if you only have 1 parameter. However, if that paramater is passed by reference, the return value does not come out if you use parenthesis:

<% OPTION EXPLICIT %>
<%

sub MakeLonger(byref something)
    something = "hello " & something 
end sub

dim msg
msg = "World"

MakeLonger(msg)
response.write msg
response.write "<br />"

MakeLonger msg
response.write msg

%>

Output is:

World 
hello World
feihtthief
A: 

classic ASP has a lot of gotchas if u never worked with it :) i would recommend having a look at ajaxed library which is a still maintained classic asp library. It helps you to get rid of most common gotchas when dealing with legacy apps.

Michal