Property Let argument ByRef is NOT ByRef ? 
Author Message
 Property Let argument ByRef is NOT ByRef ?

I have found that when declaring a Public Property Let routine (in an
ActiveX DLL MultiUse Class) with the new value argument being passed ByRef,
the behavior is still that of ByVal.

The IDL below is from a class written in VB.
The IDL for Project1.Class1 indicates that the ByRef parameters are just
that, ByRef. The argument for the sByRef and iByRef propput interfaces are
both [in, out] type*. One would expect changes to the argument within the
Property Let routine to affect the caller's variable, but that is not the
case.

Is this a bug or "By design?"
I need to know if this behavior will continue in subsequent versions of VB.
We are currently developing with VB6 SP3.

I have found 2 Q articles on similar subjects but not exactly this subject:
Q166928 and Q216481.

This code below illustrates the behavior. The behavior is consistent whether
running in the IDE or not.

Thank you for your response.

Mark Andrew
Senior Programmer / Analyst
United Recovery Systems, Inc.
Houston, TX

--
// Generated .IDL file (by the OLE/COM Object Viewer)
//
// typelib filename: <could not determine filename>

[
  uuid(C2B8940D-E0C1-11D3-AD03-00805F65015C),
  version(1.0)
]
library Project1
{
    // TLib :     // TLib : OLE Automation :
{00020430-0000-0000-C000-000000000046}
    importlib("STDOLE2.TLB");

    // Forward declare all types defined in this typelib
    interface _Class1;

    [
      odl,
      uuid(C2B8940E-E0C1-11D3-AD03-00805F65015C),
      version(1.0),
      hidden,
      dual,
      nonextensible,
      oleautomation
    ]
    interface _Class1 : IDispatch {
        [id(0x68030003), propput]
        HRESULT sByRef([in, out] BSTR* rhs);
        [id(0x68030002), propput]
        HRESULT sByVal([in] BSTR rhs);
        [id(0x68030001), propput]
        HRESULT iByRef([in, out] short* rhs);
        [id(0x68030000), propput]
        HRESULT iByVal([in] short rhs);
    };

    [
      uuid(C2B8940F-E0C1-11D3-AD03-00805F65015C),
      version(1.0)
    ]
    coclass Class1 {
        [default] interface _Class1;
    };

Quote:
};
>>Project1.Class1 (Class1.cls) <<

Option Explicit

Public Property Let sByRef(ByRef sNew As String)
    sNew = Trim(sNew)
End Property

Public Property Let sByVal(ByVal sNew As String)
    sNew = Trim(sNew)
End Property

Public Property Let iByRef(ByRef iNew As Integer)
    iNew = 3
End Property

Public Property Let iByVal(ByVal iNew As Integer)
    iNew = 4
End Property

Quote:
>>Project2.Form1 (Form1.frm)<<

Option Explicit

Private Sub Form_Load()

    Dim s As String
    Dim i As Integer

    Dim o As New Project1.Class1

    s = "c        "
    i = 1

    txt.Text = "s = """ & s & """" & vbCrLf

    txt.Text = txt.Text & "Call o.sByVal = s" & vbCrLf
    o.sByVal = s
    txt.Text = txt.Text & "s = """ & s & """" & vbCrLf

    txt.Text = txt.Text & "Call o.sByRef = s" & vbCrLf
    o.sByRef = s
    txt.Text = txt.Text & "s = """ & s & """" & vbCrLf

    txt = txt.Text & vbCrLf
    txt.Text = txt.Text & "i = " & i & vbCrLf

    txt.Text = txt.Text & "Call o.iByVal = i" & vbCrLf
    o.iByVal = i
    txt.Text = txt.Text & "i = " & i & vbCrLf

    txt.Text = txt.Text & "Call o.iByRef = i" & vbCrLf
    o.iByRef = i
    txt.Text = txt.Text & "i = " & i & vbCrLf

End Sub

Quote:
>><<

Project2 has a reference to Project1.
Form1 contains TextBox txt.

Output in TextBox txt is as follows:

s = "c        "
Call o.sByVal = s
s = "c        "
Call o.sByRef = s
s = "c        "

i = 1
Call o.iByVal = i
i = 1
Call o.iByRef = i
i = 1



Tue, 30 Jul 2002 03:00:00 GMT  
 Property Let argument ByRef is NOT ByRef ?


Quote:
> I have found that when declaring a Public Property Let routine (in an
> ActiveX DLL MultiUse Class) with the new value argument being passed
ByRef,
> the behavior is still that of ByVal.

> The IDL below is from a class written in VB.
> The IDL for Project1.Class1 indicates that the ByRef parameters are
just
> that, ByRef. The argument for the sByRef and iByRef propput
interfaces are
> both [in, out] type*. One would expect changes to the argument within
the
> Property Let routine to affect the caller's variable, but that is not
the
> case.

> Is this a bug or "By design?"

<cut>
I seem to remember that this is "by design" although I don't rememebr
where I read/heard that.  The Property Let is not normally used to
return values and it would be odd if the syntax "object.property=x"
changed the value of "x" although it looks from the code like
it "should".  Your best bet is probably to make it a public Sub:
Public Sub xyz(Byref SomeValue As String)
SomeValue=Trim$(somevalue)
End Sub

You'd have to call it with "Call Object.xyz(x)" but it would return the
value and probably be much less confusing for maintenance programming.

--
Please reply via the newsgroup only

Sent via Deja.com http://www.deja.com/
Before you buy.



Wed, 31 Jul 2002 03:00:00 GMT  
 Property Let argument ByRef is NOT ByRef ?
More info:

I do not have a problem with the assignment argument always being treated as
ByVal. In fact, that is probably preferable. I cannot think of any case
where I would actually want the Property Let routine to modify the caller's
assignment value, but that doesn't mean there is no such case, and the IDL
indicates that that is what should happen. This came up when I insisted to
our developers that all assignment arguments in Property Let routines be
explicitly declared ByVal in the argument list, rather than not explicitly
declaring, which I assumed meant it would be passed ByRef.

The problem is consistency in expected behavior and expected behavior as
indicated by the documentation. I would expect that the current behavior is
a bug. I also do not know yet if the bahavior is consistent accross machine
boundaries. I have 2 people telling me 2 different answers.

According to the documentation for the Property Let statement: "Like a
Function and Property Get procedure, a Property Let procedure is a separate
procedure that can take arguments, perform a series of statements, and
change the value of its arguments. "

If you have arguments in addition to the assignment (NewValue) argument,
these arguments behave "normally". That is, if they are ByRef (default) or
ByVal, they behave as ByRef and ByVal arguments respectively as they would
in any Function or Sub. The last argument (the assignment argument) is
always treated as ByVal even if explicitly declared ByRef. This is not
consistent in my view.

What I really need to know is if the current behavior going to be continued
in future versions of VB? If it is by design, then the answer would be yes,
if not, then no.

Is there anyone from MS that can address this question?

Thank you.

--
Mark Andrew
Senior Programmer / Analyst
United Recovery Systems, Inc.
Houston, TX



Fri, 02 Aug 2002 03:00:00 GMT  
 Property Let argument ByRef is NOT ByRef ?


Quote:
> More info:

> I do not have a problem with the assignment argument always being
treated as
> ByVal. In fact, that is probably preferable. I cannot think of any
case
> where I would actually want the Property Let routine to modify the
caller's
> assignment value, but that doesn't mean there is no such case, and
the IDL
> indicates that that is what should happen. This came up when I
insisted to
> our developers that all assignment arguments in Property Let routines
be
> explicitly declared ByVal in the argument list, rather than not
explicitly
> declaring, which I assumed meant it would be passed ByRef.

I agree 100% with that as a standard.  I always use ByRef or ByVal
explicitly in all cases just to make reading the code easier.

Quote:
> The problem is consistency in expected behavior and expected behavior
as
> indicated by the documentation. I would expect that the current
behavior is
> a bug. I also do not know yet if the bahavior is consistent accross
machine
> boundaries. I have 2 people telling me 2 different answers.

I'd consider it a compiler bug.  I totally agree that it should be
documented or there should be a warning if you declare the RHS value
ByRef when it will not be treated that way.

Quote:
> According to the documentation for the Property Let statement: "Like a
> Function and Property Get procedure, a Property Let procedure is a
separate
> procedure that can take arguments, perform a series of statements, and
> change the value of its arguments. "

> If you have arguments in addition to the assignment (NewValue)
argument,
> these arguments behave "normally". That is, if they are ByRef
(default) or
> ByVal, they behave as ByRef and ByVal arguments respectively as they
would
> in any Function or Sub. The last argument (the assignment argument) is
> always treated as ByVal even if explicitly declared ByRef. This is not
> consistent in my view.

Mine either -- if it allows the syntax then it should respect the
syntax.

Quote:
> What I really need to know is if the current behavior going to be
continued
> in future versions of VB? If it is by design, then the answer would
be yes,
> if not, then no.

I don't see it as making any difference whether they fix it to reject
the syntax or fix it to allow ByRef under some conditions.  My stnadard
is to declare it ByVal always and never code anything that expects to
be able to change that parameter.  That behavior will be maintained (or
every single app in the world that uses property let will break) so
whatever else they do with it will not affect me.  If there is a change
in later versions I can always evaluate it and possibly change my
coding style to allow for it.  Whether that happens or not I know the
existing code is OK.

--
Please reply via the newsgroup only

Sent via Deja.com http://www.deja.com/
Before you buy.



Sat, 03 Aug 2002 03:00:00 GMT  
 
 [ 4 post ] 

 Relevant Pages 

1. ByRef or not ByRef, that is the array?

2. ByRef Argument Type Mismatch

3. ByRef Argument Type mismatch

4. argument type ByRef incompatibly

5. Event Arguments : ByRef or ByVal (Which Best)?

6. Getting a Compile Error: ByRef argument type mismatch

7. Pass arguments ByVal or ByRef

8. VB6 ByRef argument type mismatch

9. Passing arguments ByRef from VBScript to COMAdmin component

10. ByRef arguments

11. Passing arguments ByRef to Script Control 1.0

12. VBScript ByRef argument to VB DLL in IIS-5

 

 
Powered by phpBB® Forum Software