ASP arguments (in VBScript)- byval or byref

When an argument is passed to a function or sub, is the argument passed by value or by ref?
ronandersenAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

pure032398Commented:
G'Day. Lets hope i can answer this right for you.

I've answered the question, then given an example. Then i've made a second suggestion, as a side note relating to the question,


ANSWER:
^^^^^^^^
If the code is in ASP, then the arguments are passed by VALUE.

ANSWER: BY VALUE.


Eg to clarrify the question
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
<<in the middle of some ASP code>>
Do While NOT rsUse.EOF

   intTotal = CalculateTotal (rsUse("intSubTotal"), intCurrentTotal)


'  If i try to check the answers,
'  they should both be different....
   response.write "intTotal: ["& intTotal &"]<BR>"
   response.write "intCurrentTotal: ["& intCurrentTotal &"]<BR>"


   rsUse.MoveNext
Loop



<<bottom of code>
' Notice i've used the SAME VAR NAME
' 'intCurrentTotal' to check if it's
' passed by ref or val....
Function intTotal (intSomeAmount, intCurrentTotal)
  Dim intReturnAmount

  intReturnAmount = intCurrentTotal+ intSomeAmount

  return intReturnAmount
End Function


SUB-ANSWER #2
^^^^^^^^^^^^^
  To complicate things, you can REFERENCE other variables inside a function.

EG. in the above senario, i PASS 2 arguments: current amount AND the current outstanding total amount. I could have NOT PASSED the second one - current outstanding amount - but REFERENCED THAT inside the function...

eg.
^^^^

<<in the middle of some ASP code>>
Do While NOT rsUse.EOF

'  This proves the variable exists...
   response.write "intCurrentTotal: ["& intCurrentTotal &"]<BR>"

   intTotal = CalculateTotal (rsUse("intSubTotal"))


'  If i try to check the answers,
'  they should both be different....
   response.write "intTotal: ["& intTotal &"]<BR>"
   response.write "intCurrentTotal: ["& intCurrentTotal &"]<BR>"


   rsUse.MoveNext
Loop



<<bottom of code>
' Notice i've used the SAME VAR NAME
' 'intCurrentTotal' to check if it's
' passed by ref or val....
Function intTotal (intSomeAmount)
  Dim intReturnAmount

  intReturnAmount = intCurrentTotal+ intSomeAmount

  return intReturnAmount
End Function



SEE THE DIFFERENCE???

If this all doesn't make sence, then just comment away.


NOTE: This is all browser code (untested), but it looks ok as i scan over it.

ENJOY
0
clockwatcherCommented:
Actually, I believe you're wrong.  By default, they're passed by reference.  If you want to pass by value, you have to specify it.

Here's a simple test:

<%

sub ByVal_Or_ByRef(myVariable)

  myVariable = 3

end sub


myTest = 5

ByVal_Or_ByRef myTest

if myTest = 5 then
  response.write "Passed by Value"
else
  response.write "Passed by Reference-- myTest = " & myTest
end if

%>
0
pure032398Commented:
umm...

****.


i appologise =)

oh well. back to the drawing board.


sorry about that. hope i didn't confuse you.

-PK-
0
Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

ronandersenAuthor Commented:
Well believe it or not both of you are wrong, and actually PURE - you were right!


This quote is straight from the "Learning VBScript" book from O'Reilly. Page 139.

"VBScript, unlike VBA or VB, does not support the ByRef keyword, nor does it allow you to pass values by reference to subroutines. This makes the behavior of VBScript quite different from VBA(or VB); whereas VBA by default passes variables to subroutines by reference, VBScript only passes variables to them by value".

Sorry Guys!!
0
rupertsCommented:
mmm I agree with the Value theory above!
(ron andersen)

Which is strange when you compare vbscript with VB!?!
0
clockwatcherCommented:
Either you're taking it out of context or it's incorrect.  The code I posted above proves that it passes by reference.  Try the above code out and tell me I'm wrong.

In their testing, they probably did something erroneous and used parenthesis when passing the value.  Parenthesis are not required in the call and actually probably cause the routine to look like it passes by value when it's actually passing by reference.  The parenthesis more than likely cause the variable to be copied into a separate location and then passed:

Compare this which looks like it passes by value, but IMHO it's actually still passing by reference, it's just passing a copy.

<%

sub ByVal_Or_ByRef(myVariable)

  myVariable = 3

end sub


myTest = 5

ByVal_Or_ByRef(myTest)

if myTest = 5 then
  response.write "Passed by Value"
else
  response.write "Passed by Reference-- myTest = " & myTest
end if

%>

With the proper call-- which is definitely passing by reference.

<%

sub ByVal_Or_ByRef(myVariable)

  myVariable = 3

end sub


myTest = 5

ByVal_Or_ByRef myTest

if myTest = 5 then
  response.write "Passed by Value"
else
  response.write "Passed by Reference-- myTest = " & myTest
end if

%>
0
clockwatcherCommented:
Sorry those should have been separated better.  

Incorrect call with parenthesis (making it appears as a ByVal)

<%

sub ByVal_Or_ByRef(myVariable)

  myVariable = 3

end sub


myTest = 5

ByVal_Or_ByRef(myTest)

if myTest = 5 then
  response.write "Passed by Value"
else
  response.write "Passed by Reference-- myTest = " & myTest
end if

%>

----------------------------------------
Correct calling procedure without parens-- which is definitely a ByRef

<%

sub ByVal_Or_ByRef(myVariable)

  myVariable = 3

end sub


myTest = 5

ByVal_Or_ByRef myTest

if myTest = 5 then
  response.write "Passed by Value"
else
  response.write "Passed by Reference-- myTest = " & myTest
end if

%>

0
rupertsCommented:
OK even I'm confused now...

I read "default passes variables to subroutines by reference," which I thought was relating VB Script hence ASP, when it is actually refering to VB!

I agree with clockwatcher - by reference!! The book must be wrong!






0
clockwatcherCommented:
Don't always believe what you read.  

After re-reading your post, I noticed that the book says VBScript doesn't even support the ByRef keyword.  That's 100% wrong.  I can understand the possible mistake about ByVal by default (as I posted above), but not supporting ByRef is 100% blatantly wrong.

http://msdn.microsoft.com/scripting/default.htm?/scripting/vbscript/doc/vsstmSub.htm

The default under VBScript is the same as it is under VB-- ByRef.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
rupertsCommented:
OK..

A little more research..

Functions pass by value
Sub's pass by reference.


(Run Clockwatcher's code for subs, and my shify code for functions!

<%
function ByVal_Or_ByRef2(myVariable)
  myVariable = 3
  ByVal_Or_ByRef2 = "<BR>Function Run<BR>"
end function

myTest = 5

response.write(ByVal_Or_ByRef2(myVariable))

if myTest = 5 then
  response.write "<BR>Passed by Value"
else
  response.write "<BR>Passed by Reference-- myTest = " & myTest
end if
%>
0
rupertsCommented:
Mr Clockwatcher..

A bit outragous to propose an answer when you've only answered half of the question!

"argument is passed to a function or sub"


0
clockwatcherCommented:
Ruperts-- try again-- without throwing in the confusion of response.write and Cstr.

;-)

<%

sub ByVal_Or_ByRef(myVariable)

  myVariable = 3

end sub

function ByVal_Or_ByRef2(myVariable)
 
  myVariable = 3
  ByVal_Or_ByRef2 = 2

end function

myTest = 5
ByVal_Or_ByRef myTest
if myTest = 5 then
  response.write "Sub Passed by Value"
else
  response.write "Sub Passed by Reference-- myTest = " & myTest
end if

Response.Write "<BR>"


myTest = 5
myanswer = ByVal_Or_ByRef2(myTest)
if myTest = 5 then
  response.write "Function Passed by Value"
else
  response.write "Function Passed by Reference-- myTest = " & myTest
end if


%>
0
clockwatcherCommented:
Actually ruperts after looking at your code, you passed the wrong variable. :-)

<%
function ByVal_Or_ByRef2(myVariable)
  myVariable = 3
  ByVal_Or_ByRef2 = "<BR>Function Run<BR>"
end function

myTest = 5

response.write(ByVal_Or_ByRef2(myVariable))

if myTest = 5 then
  response.write "<BR>Passed by Value"
else
  response.write "<BR>Passed by Reference-- myTest = " & myTest
end if
%>

You passed myVariable rather than myTest.

;-)
0
ronandersenAuthor Commented:
Clockwatcher,

I am going to test your code tomorrow at work(I do not have access to VBScript at home). I have an example where the code uses the pass by ref, but it does not work. Let me double check my code. If it still does not work, I'll post it. The only difference I see between my example and your example is that I declare the variable in questions with a Dim statement before initializing it..

- I'll be back!
0
ronandersenAuthor Commented:
ClockWatcher,

Here is what I found...

If you pass a variable to a sub or function using a parenthesis, then a copy of the argument is passed to the sub/function. If you call a sub or function without a parens, then it is passed by reference.

In one of your previous post.. what does the following mean?

Compare this which looks like it passes by value, but IMHO it's actually still passing by reference, it's just passing a copy.

This states that it is still being passed by ref; however, when you execute your example using parens, it does not change the original value, which  means it is actually being passed by value.

Also.. what does the following mean(previous post)...

Incorrect call with parenthesis (making it appears as a ByVal)

All the examples in the Wrox's Beginning ASP book and MS Site Servers examples, use parens when passing arguments..


Please explain??

0
ronandersenAuthor Commented:
Clockwatcher..


Finally,

The book is correct!!!

Although VBScript recognizes byRef, it does not support it. Using your own example..

sub ByVal_Or_ByRef( byRef myVariable)

  myVariable = 3

end sub


myTest = 5

ByVal_Or_ByRef(myTest)

if myTest = 5 then
  response.write "Passed by Value"
else
  response.write "Passed by Reference-- myTest = " & myTest
end if

The result of this example is byValue, which proves that VBScript does not support byRef. Regarding using parens, it is good programming practice to use parens when coding, for not only is it a coding standard, but also it is easier to maintain, especially when you have a list of arguments. Nevertheless, you gave the best answer from all teh experts, although it is partially true..
 
0
clockwatcherCommented:
Ron,

Sorry to tell you this, but it's NOT good programming practice to use parens when calling a subroutine.  Actually, in VB it's illegal.  In VBScript, it's allowed but incorrect.  If you WANT to use parenthesis with a subroutine the PROPER way to do it is with the 'CALL' statement.

I don't know where you keep pulling out these blatantly wrong statements ("it's good programming practice to use parens"-- that one's a good laugh), but if it's from that O'Reilly book.  I'd seriously suggest getting another one.  

Try it again with the PROPER CALLING PROCEDURE.

sub ByVal_Or_ByRef( byRef myVariable)

  myVariable = 3

end sub


myTest = 5

Call ByVal_Or_ByRef(myTest)

if myTest = 5 then
  response.write "Passed by Value"
else
  response.write "Passed by Reference-- myTest = " & myTest
end if
0
clockwatcherCommented:
Actually, you can remove the byRef.  It's the default.  As I told you earlier, using the parens in the incorrect way is causing it to pass a copy of the variable.
0
rupertsCommented:
sub ByVal_Or_ByRef( byRef myVariable)
  myVariable = 3
end sub

should actually read...

sub ByVal_Or_ByRef( byRef myVariable)
  myTest = 3
end sub

Anyway..

This seems to be the answer..
-sub (in-brackets) = passes value
-sub no-brackets = passes reference.
-function = uses reference
0
clockwatcherCommented:
No ruperts-- it shouldn't.  If you changed that way, obviously it's going to make the change to the global variable 'myTest'.
0
clockwatcherCommented:
I can't believe I'm wasting so much time on this question.  It's ByRef-- Unless you call the subroutine incorrectly and use parenthesis without the Call statement-- which if VBScript was a little more strict would really cause an error.
0
rupertsCommented:
oh bollox?!? I didn't even c'n'p correctly..

lets move on! Rupert
0
clockwatcherCommented:
The sad thing is--

After all this, the guy's probably going to give me a 'C' and still think his book is right.  He's proven me wrong by improperly calling his subroutine.
0
clockwatcherCommented:
Actually, here's the VB version with his calling method.

Option Explicit

Sub testing(myvar As Integer)
 
    myvar = 3
   
End Sub

Sub main()
 
  Dim x As Integer
   
  x = 20
  testing (x)
  Debug.Print x
 
End Sub

Wait!!! What's up with that VB uses ByVal too!!! Let's start a discussion does VB use ByVal or ByRef.  Does VB even support ByRef???  ;-)

The correct way to do it under VB (as well as VBScript) if you want to use parenthesis is to use Call-- otherwise forget the parenthesis.

----------------------------------------
Option Explicit

Sub testing(myvar As Integer)
 
    myvar = 3
   
End Sub

Sub main()
 
  Dim x As Integer
   
  x = 20
  Call testing(x)
  Debug.Print x
 
End Sub
0
ronandersenAuthor Commented:
ClockWatcher,

Ok... The problem is semantics(I agree VBScript is not strict!):

If you call a procedure using the CALL statement, then you must wrap the argument list in parentheses if you want the reference.

If you call a procedure without using the CALL statement, then you do not use parens if you want the reference.

In addition to your answers, this explains it well(call section):

http://www.bl.ac.yu/manuals/vbscript/ch19fi.htm

0
clockwatcherCommented:
Thanks for the 'A' and I think you actually increased the points.  I appreciate it, but that wasn't necessary.  This should have been an easy question (and the 50 points you originally devoted to it was more than enough), it's just sometimes very difficult to convince people.

I hope after all this rambling that it's actually clear that VBScript does pass by reference.

Thanks again.
0
ronandersenAuthor Commented:
Clockwatcher,

Thankyou for your help!!
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
ASP

From novice to tech pro — start learning today.