How to find Me in a library procedure

  • Thread starter Thread starter Academia
  • Start date Start date
A

Academia

I have a procedure and in the procedure I use "Me"
Since I have multiple copies of this procedure in various places I place it
into a library as a Shared Sub.

The problem is in the library I can't use Me so I add an argument like:
( ByVal c as Control, ...)

and call it with Me as the parameter:
Library.DoSub(Me, ...)

Is there a another way?

Can't the procedure figure out who c is from the stack some how?

I've been looking at StackTrace but can't see the solution there.

Can you suggest how this can be done?

Thanks in advance
 
Academia said:
I have a procedure and in the procedure I use "Me"
Since I have multiple copies of this procedure in various places I
place it into a library as a Shared Sub.

The problem is in the library I can't use Me so I add an argument
like: ( ByVal c as Control, ...)

and call it with Me as the parameter:
Library.DoSub(Me, ...)

Is there a another way?

Your intention is not clear to me, but maybe inheritance is the way to
go: Put the sub into a base class and derive all other controls from it.
The sub will be there in all derived controls without copying anything.
You can put the base class into a library, then.

Can't the procedure figure out who c is from the stack some how?

I've been looking at StackTrace but can't see the solution there.

Can you suggest how this can be done?

Thanks in advance



Armin
 
Suppose in usercontrols you did this offten:
debug.writeline(Me.name)
....more code

So in your library, MyLibrary, you wrote a sub
Public Shared Sub ListName(ByVal c as control)
debug.writeline(c.name)
....more code
end sub

and in the usercontrols replaced
debug.writeline(Me.name)
....more code
with
MyLibrary.ListName(Me)

I'd like to change to:
Public Shared Sub ListName()
Dim c as control = ???? 'Figure out who called
debug.writeline(c.name)
....more code
end sub

and call it from the usercontrol
MyLibrary.ListName()

I hope that is clearer
Thaanks
 
Academia said:
Suppose in usercontrols you did this offten:
debug.writeline(Me.name)
...more code

So in your library, MyLibrary, you wrote a sub
Public Shared Sub ListName(ByVal c as control)
debug.writeline(c.name)
...more code
end sub

and in the usercontrols replaced
debug.writeline(Me.name)
...more code
with
MyLibrary.ListName(Me)

I'd like to change to:
Public Shared Sub ListName()
Dim c as control = ???? 'Figure out who called
debug.writeline(c.name)
...more code
end sub

and call it from the usercontrol
MyLibrary.ListName()

I hope that is clearer

My suggestion is still the same:

class myBasecontrol
inherits control
sub listname
debug.writeline(me.name)
end sub
end class

class myDerivedControl1
inherits myBasecontrol
sub x
listname
end sub
end class

class myDerivedControl2
inherits myBasecontrol
sub y
listname
end sub
end class


If this is the right solution depends on the purpose of your (real)
reusable function.


Armin
 
I understand what you're suggesting now.

I have a few subs and was hoping I could do it a way that admits to adding
to existing code easily.
That is, I was hoping I could use reflection, stack or something to discover
the object that called the sub.

Public Shared Sub ListName()
Dim c as control = ???? 'Figure out who called
debug.writeline(c.name)
....more code
end sub

It's probably not possible to do it this way.


thanks
 
Academia said:
I understand what you're suggesting now.

I have a few subs and was hoping I could do it a way that admits to
adding to existing code easily.
That is, I was hoping I could use reflection, stack or something to
discover the object that called the sub.

Public Shared Sub ListName()
Dim c as control = ???? 'Figure out who called
debug.writeline(c.name)
...more code
end sub

It's probably not possible to do it this way.

Usually, a called procedure should never care about it's caller. What's
wrong with inheritance? If you have a bunch of procedures that accept a
Control as the first argument, it's obviously an indication to
encapsulate them in your own class derived from Control (dropping the
(explicit) Control parameter).


Armin
 
Thanks

Armin Zingler said:
Usually, a called procedure should never care about it's caller. What's
wrong with inheritance? If you have a bunch of procedures that accept a
Control as the first argument, it's obviously an indication to
encapsulate them in your own class derived from Control (dropping the
(explicit) Control parameter).


Armin
 
Hi Armin,

Armin Zingler said:
Usually, a called procedure should never care about it's caller.

For Shared methods that is correct; for instance methods the object
reference has to be put on the stack in the calling code.
What's
wrong with inheritance? If you have a bunch of procedures that accept a
Control as the first argument, it's obviously an indication to
encapsulate them in your own class derived from Control (dropping the
(explicit) Control parameter).

Inheritance simply would not work with TextBox and ComboBox because you
can't inject that common method into an already diverse tree.

As of VB2008, there is extension methods which allows for Shared methods to
be called similar to an instance method, and does not suffer the same
problem inheritance does. See:
http://visualstudiomagazine.com/columns/article.aspx?editorialsid=2078
 
Bill McCarthy said:
Hi Armin,



For Shared methods that is correct; for instance methods the object
reference has to be put on the stack in the calling code.

Yes, it's on the stack but it's just another argumetn. The called
procedure still doesn't care from where it has been called. This is true
for shared and instance methods.
Inheritance simply would not work with TextBox and ComboBox because
you can't inject that common method into an already diverse tree.

I sometimes don't understand why it is said that "it does not work
if...". Why not wait until the OP tells us if it is applicable in his
situation? Inheritance is one possible solution.
As of VB2008, there is extension methods which allows for Shared
methods to be called similar to an instance method, and does not
suffer the same problem inheritance does. See:
http://visualstudiomagazine.com/columns/article.aspx?editorialsid=2078



Armin
 
Armin Zingler said:
Yes, it's on the stack but it's just another argumetn. The called
procedure still doesn't care from where it has been called. This is true
for shared and instance methods.

Well it depends. The point is with an instance method, the "Me" reference
he wanted is on the call stack. If he compiles and marks those methods not
to be inlined, he could possibly get a reference to the "Me" object he
seeks, although that might require a debugger to be attached. (similar to
using CallStack, but references rather than the strings)
I sometimes don't understand why it is said that "it does not work if...".
Why not wait until the OP tells us if it is applicable in his situation?
Inheritance is one possible solution.

Inheritance is a very limited solution, and for the reasons outlined above,
it is easily broken. Even if it does work for him today, it is jsut as
likely to be broken again for the same design reasons. I feel it is better
to tell people the pros and cons of things, not just give them a band aid
that may work.
 
Bill McCarthy said:
Well it depends.

No, it never depends. Depend means: analyzing the stack trace and
execute code depending on the caller.
The point is with an instance method, the "Me"
reference he wanted is on the call stack. If he compiles and marks
those methods not to be inlined, he could possibly get a reference
to the "Me" object he seeks, although that might require a debugger
to be attached. (similar to using CallStack, but references rather
than the strings)

I don't understand your concern at all. All I said is that a
procedure should be defined by determining it's purpose, it's in/out
parameters and it's function return values (if exists). The procedure
/never/ cares from where it has been called (apart from few Reflection
scenarios). "Me" is just an implicit argument, but it's still only an
argument, an OOP syntax agreement. From the procedure's point of few,
it's just one more argument, so why make a distinction between
instance and shared methods? There is no difference. Both have
arguments and both don't care about who called them.
Inheritance is a very limited solution,

Really? Not in my experience.
and for the reasons outlined above, it is easily broken.

If you find a fitting case, you are right. In most cases, above all the
one the OP mentioned, it is very probable the best solution. Let's
wait...
Even if it does work for him today, it
is jsut as likely to be broken again for the same design reasons. I
feel it is better to tell people the pros and cons of things, not
just give them a band aid that may work.

I don't see the sense of this statement. This sounds like declining
inheritance at all because "there might be reasons in the future...".
Well, I just look at the /current/ problem and think I propsed a good
solution.

This is only available in VB2008. Maybe he is using VB2005? Why do you
suggest something that the OP might not be able to use? ... just
kidding. ;)


Armin
 
Hi Armin,


Armin Zingler said:
No, it never depends. Depend means: analyzing the stack trace and
execute code depending on the caller.

Right which you can do if the calling code is an instance method. If it is
a shared method you cannot.

I don't understand your concern at all. All I said is that a
procedure should be defined by determining it's purpose, it's in/out
parameters and it's function return values (if exists). The procedure
/never/ cares from where it has been called (apart from few Reflection
scenarios). "Me" is just an implicit argument, but it's still only an
argument, an OOP syntax agreement. From the procedure's point of few,
it's just one more argument, so why make a distinction between
instance and shared methods? There is no difference. Both have
arguments and both don't care about who called them.

See above.

Really? Not in my experience.


Yes really. Interfaces are typically far more flexible for example.

If you find a fitting case, you are right. In most cases, above all the
one the OP mentioned, it is very probable the best solution. Let's
wait...


Again, I think you have misread what I said. I believe it is best to
provide the pros and the cons, not just something that may happen to work
this time.

I don't see the sense of this statement. This sounds like declining
inheritance at all because "there might be reasons in the future...".
Well, I just look at the /current/ problem and think I propsed a good
solution.


Really ? So let's say he does put that in a base class somewhere in the
Control tree hierarchy. (note he did mention Control before). Just how
useful is that really going to be ? It's more likely it would cause him a
lot more re-inventing the wheel


This is only available in VB2008. Maybe he is using VB2005? Why do you
suggest something that the OP might not be able to use? ... just
kidding. ;)

I made it pretty clear with the "As of 2008" as to the limitation. See the
difference ?
 
Academia,

If you use this,
Library.DoSub(Me, ...)
Than the receiver can only be in general
Public Sub(<name> as Object, ....

If you do this by instance from a form class than the receiver can be
Public Sub(<name> as Form, ...........)
or because that Forms inherits from Control
Public Sub(<name> as Control, ..............)

Cor
 
Bill McCarthy said:
Right which you can do if the calling code is an instance method. If
it is a shared method you cannot.

Right, but you don't do it in /both/ cases because you have all the
information in the arguments.
Yes really. Interfaces are typically far more flexible for example.

He is talking about his self-written functions. How can he put them into
an Interface?
Again, I think you have misread what I said. I believe it is best
to provide the pros and the cons, not just something that may happen
to work this time.

I understand, but /I/ usually don't decline a /possible/ solution
because it /might/ not be applicable. If you had any information that I
may have missed and that makes my proposal not applicable, I would have
understood it better.
Really ? So let's say he does put that in a base class somewhere in
the Control tree hierarchy. (note he did mention Control before). Just
how useful is that really going to be ? It's more likely it
would cause him a lot more re-inventing the wheel

Guess where the code is located that currently contains the code passing
"Me" as an argument. It /must/ be in his /own/ Control (better: class
derived from Control), otherwise he wouldn't be able to pass "Me".
That's the point you might have overlooked. As he wants to be able to
call the procedure from any of his controls, the situation is screaming
for a common base class, derived from Control. The type "control" was
only used because he currently does /not/ have such a base class. That's
what I read from the information given. Yes, maybe this will prove
false, but currently there is no indication of it.
I made it pretty clear with the "As of 2008" as to the limitation. See
the difference ?

You saw "just kidding. ;)"? It was only to make clear that you did the
same with my solution even as I wrote "If this is the right solution
depends on the purpose of your (real) reusable function."

No need to elaborte on this further. I do see the cons of my solution,
but I still think that Inheritance is probably the best approach in the
situation. I suggest: Let's wait (if) what the OP says (anything).


Armin
 
Hi Bill,

Armin is one of the longest and most respected community members of the
International and German VB for Net newsgroups and at least I want to keep
it like that.

He has no problems with any discussion, however in my idea is he not waiting
on a learning tone from a MVP.

Be aware however that in answering questions, we don't always want to be
exactly correct.
That an OP understand it and helped with that is more important than any
theoretical explanation.

I know that Armin knows more from VB (including VB6) than a lot of MVP's

If you want any deeper information about that, then mail Jay, Herfried or
me.

Sorry Armin, I could not resist.

Cor
 
Hi Armin,

Armin Zingler said:

yes ;)
but you don't do it in /both/ cases because you have all the
information in the arguments.

Only if he changes it to be so.

He is talking about his self-written functions. How can he put them into
an Interface?

Very easily. You implement an Interface for any extra information you might
need and use that as the qualifier for an extension method.

I understand, but /I/ usually don't decline a /possible/ solution
because it /might/ not be applicable. If you had any information that I
may have missed and that makes my proposal not applicable, I would have
understood it better.

Well if you do understand, I don't see why you seem to be getting so bent
out of shape. The criticisms I put forward are valid. You in response to
that attacked the idea of criticizing something. Draconian at best.


Guess where the code is located that currently contains the code passing
"Me" as an argument. It /must/ be in his /own/ Control (better: class
derived from Control), otherwise he wouldn't be able to pass "Me".
That's the point you might have overlooked. As he wants to be able to
call the procedure from any of his controls, the situation is screaming
for a common base class, derived from Control. The type "control" was
only used because he currently does /not/ have such a base class. That's
what I read from the information given. Yes, maybe this will prove false,
but currently there is no indication of it.


So we come at things from different perspectives and different experiences.
In my experiences, very little is achieved by deriving from Control directly
as you then have to reinvent the wheel completely. More often people extend
existing controls, and hence the feedback I provided was based on that. I
shouldn't have to justify that to you, should I ?


You saw "just kidding. ;)"? It was only to make clear that you did the
same with my solution even as I wrote "If this is the right solution
depends on the purpose of your (real) reusable function."

No need to elaborte on this further. I do see the cons of my solution,
but I still think that Inheritance is probably the best approach in the
situation. I suggest: Let's wait (if) what the OP says (anything).

Great. Then why the response when I did post the cons which you clearly had
not ?
 
Cor Ligthert said:
Sorry Armin, I could not resist.

Thanks for the kind words, Cor! I really appreciate all your
contributions, too. However, please no personality discussion. I don't
feel that Bill was disrespectful. I only think it was a kind of
misunderstanding each other.


Armin
 
Bill McCarthy said:
Hi Armin,



yes ;)


Only if he changes it to be so.

So what? I made a general statement that a procedure should be an
encapsulated task. If he has to change anything, be it so. He wanted a
suggestion. I gave one.
Very easily. You implement an Interface for any extra information
you might need and use that as the qualifier for an extension
method.

You should have mentioned that you meant a /combination/ of extension
methods and interfaces. As long as I am the author of the class, I
extend the class by adding instance members, not by adding extension
methods. Extension methods make sense if you are not the author.
Obviously he is the author, otherwise he couldn't pass "Me".
Well if you do understand, I don't see why you seem to be getting so
bent out of shape. The criticisms I put forward are valid. You in
response to that attacked the idea of criticizing something. Draconian
at best.

Not at all. Just was surprised about your criticism of a valid solution
made in advance. Completely unnecessary IMO.

Um.. yes.
Great. Then why the response when I did post the cons which you
clearly had not ?

My lack of knowledge of the English language disables me to understand
this, but don't bother...


Armin
 
Hi Armin,

Armin Zingler said:
So what? I made a general statement that a procedure should be an
encapsulated task. If he has to change anything, be it so. He wanted a
suggestion. I gave one.

I suggest you look at my original response and the posters original
question. (the OP asked about the stack state)


You should have mentioned that you meant a /combination/ of extension
methods and interfaces. As long as I am the author of the class, I extend
the class by adding instance members, not by adding extension methods.
Extension methods make sense if you are not the author. Obviously he is
the author, otherwise he couldn't pass "Me".


Again, as I have pointed out, inheritance only works if you are the author
of the common base class . With controls that is rarely the case.


Not at all. Just was surprised about your criticism of a valid solution
made in advance. Completely unnecessary IMO.


Well this is a public forum, and I'd expect people to learn and share ideas,
not just settle for the first one that is put forward.




Say what ?



My lack of knowledge of the English language disables me to understand
this, but don't bother...


Can't help you there.
 
Thanks Cor.
I've given up on finding the caller in a library sub.
I'll simply change everywhere to passing Me.

I did see on the Internet something like:

Public sub Mysub(this ByVal a, ..
(I don't remember exactly)
But I couldn't understand what it was for.

Thanks again
 
Back
Top