Passing ByRef...

I am using VB6.0 Enterprise Edition.

I am trying to pass ByRef a class property (defined as  public string in the class) to a function which modifies that value. On returning back from the function the class property remains unchanged. The behaviour is exactly as if the property was being passed ByVal although I am explicitly mentioning ByRef. Why is this so? Is this a VB bug?

Code example:
Class Name: cls
'in cls
Public str as string

Form1:
Sub Form1_click()
    Dim o_cls as cls
   
    Set o_cls = New cls
   
    o_cls.str = "abc"
    Msgbox "Before: " & o_cls.str
    Modify o_cls.str
    Msgbox "After: " & o_cls.str
   
    set o_cls = Nothing

End Sub

Private Function Modify(arg as string)
    arg = "abcChanged"
End Function
arvind_csAsked:
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.

DrDelphiCommented:
what you would want to do is this:

Private Function Modify(byref arg as string)
    arg = "abcChanged"
End Function

VB passes BYVAl by default

Good luck!!





0
DrDelphiCommented:
Opps! Forgot to add:

This should be a SUB, since you never look at the result of the function.


Cheers!
 
0
Éric MoreauSenior .Net ConsultantCommented:
DrDelphi,

VB passes ByRef by default.

This is extracts from the VB Help:

ByRef Optional. Indicates that the argument is passedby reference. ByRef is the default in Visual Basic.
"
0
The Ultimate Tool Kit for Technolgy Solution Provi

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy for valuable how-to assets including sample agreements, checklists, flowcharts, and more!

arvind_csAuthor Commented:
DrDelphi, as everybody knows, VB passes ByRef by default. It really should not matter whether the funtion Modify returns anything as that is not my point of contention.
 My question is simple: why does VB pass by value in this case when I have explicitly mentioned ByRef? At the very least a compile time error should have been generated.
0
Éric MoreauSenior .Net ConsultantCommented:
You have to pass your object byref like this:

Your class:
Option Explicit

Public intX As String
Public strX As String

Your Form:
Sub Form_click()
Dim o_cls As cls
     
    Set o_cls = New cls
     
    o_cls.strX = "abc"
    o_cls.intX = 1
    MsgBox "Before: " & o_cls.strX & " - " & o_cls.intX
    Modify o_cls
    MsgBox "After: " & o_cls.strX & " - " & o_cls.intX
     
    Set o_cls = Nothing

End Sub

Private Function Modify(ByRef clsX As cls)
    clsX.strX = "abcChanged"
    clsX.intX = 55
End Function
0
DrDelphiCommented:
emoreau,
  I stand corrected.<g>
 
0
arvind_csAuthor Commented:
Thanks, emoreau but I know that it can be done by passing the object itself (I reached this conclusion before posting the question). I do not want to be a nag but my original query still remains unanswered: Is this a bug? I am asking this as I have just learnt that passing object properties ByRef is possible in VB4.0. Why is version 6.0 so special that it screws up?
0
DrDelphiCommented:
What happens if you put a breakpoint on the line prior to the call to Modify? Stepping in Modify, does Arg read "abc"?
At what point does it lose it's value?

And should you have have to pass the entire class byref? The elemenet of of the class (str) is already instanciated with a value. From there you should be able to do whaetver you like with it, no?
0
Éric MoreauSenior .Net ConsultantCommented:
This is not a bug with ByRef!

This behavior is caused by the presence of your class! Change your properties by variables in your form and values will be changed.
0
arvind_csAuthor Commented:
Thanks, emoreau but I know that it can be done by passing the object itself (I reached this conclusion before posting the question). I do not want to be a nag but my original query still remains unanswered: Is this a bug? I am asking this as I have just learnt that passing object properties ByRef is possible in VB4.0. Why is version 6.0 so special that it screws up?
0
VbmasterCommented:
This is because the compiler translates the public string to a public property. It's not a bug, it's meant to be this way.
0
MinnaCommented:
arvind_cs,
It has nothing to do with ByRef.  It's the way your program is written.  You've passed a copy of the value of class variable to the function (regardless of whether you include ByRef in the argument list) and not the actual class object itself which is the only way to change the class variable.  Your original value is still hanging around in memory.  That's why it doesn't change the value after you exit the function.
0
Jeremy_DCommented:
To elaborate on this a little further, look at it this way:
The reference o_cls.str is not really a variable, it's a call to a property, which is about the same as a call to a function. VB will evaluate this reference before calling the Modify function, and the evaluation will result in a literal value, the contents of the property.
To get what you want, you can either pass a reference to the object, as mentioned by emoreau, or do it this way

'-----------------------------------
Private Function Modify(ByVal arg as String) as String
    Modify = "abcChanged"
End Function

o_cls.str = Modify(o_cls.str)
'-----------------------------------

or, yet another solution (also mentioned by emoreau before, but not explained), use a local temporary variable:

'-----------------------------------
strTemp = o_cls.str
Modify strTemp
o_cls.str = strTemp
'-----------------------------------

Just keep in mind that a property is *not* a variable, and therefore can never be passed ByRef. It's got all the habits of a Function call, so you should treat it as that.

Hopes this clarifies, cheers,
Jeremy

0
paul_tsekovCommented:
VB passes ByRef by default.
Remember that, DrDelphi !!!!!!!!!
0
DrDelphiCommented:
way to beat that ole dead horse there,Paul... I acknowldeged my error already. But you hang in there...
0
paul_tsekovCommented:
Hi VBfan,
I think I solved your problem.
Try to declare

dim o_cls as cls
set o_cls=new cls

not in you click event module,
but in you Form module level, so
o_cls to become global for the whole Form module !!!!
Code example:
Class Name: cls
'in cls
Public str as string

Form1:
Option Explicit

    Dim o_cls as cls
    Set o_cls = New cls

Sub Form1_click()
    o_cls.str = "abc"
    Msgbox "Before: " & o_cls.str
    Modify o_cls.str
    Msgbox "After: " & o_cls.str
End Sub

Private sub Form_Unload()
    set o_cls = Nothing
End Sub
   
Private Function Modify(ByRef arg as string)
    arg = "abcChanged"
End Function

if you declare o_cls in your click event procedure, when you call the Modify function it works with a copy of o_cls, not with o_cls.

BUT, when you declare o_cls as GLOBAL object in your Form module, as shown above, when you call the Modify function , it works with o_cls, not with his copy.

So, in your case you should make o_cls global, for the function Modify to work correctly !!!!!!


            Pavel Tsekov
       email : paul_tsekov@yahoo.com



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
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
Visual Basic Classic

From novice to tech pro — start learning today.