Self vs Me: Class subclassed from Canvas

Self vs Me. Sometimes you can get away with using Me in code that would be better (in the sense of clarity) by using Self. I try and stay on the right side of the street when coding to avoid confusion.

The documentation says in an entry on the topic of Me vs. Self:

If you use the Me prefix outside of a control’s event handler on a DesktopWindow/WebPage/MobileScreen (such as in a method), then Me will work the same as Self. To prevent confusion, you should refrain from using the Me prefix outside of control event handlers on DesktopWindows/WebPages/MobileScreens.

When working with classes and subclasses you have added to your project, you should always use Self (or nothing since Self is the default). This is true even if you create a control subclass and are implementing its event handlers. Again, you only use Me when in the event handler for a control (or class) that is added to a DesktopWindow/WebPage/MobileScreen.

You could take away from this, that you should never see the prefix Me outside the event handler of a control.

Am I correct in observing that another valid location for Me is in the Methods of a Class whose super is Canvas?

I have such a Class. One of the properties of a Canvas is Window. If you are writing Methods for this Class and you wanted to refer to the Window in which it happens to exist (say to figure out the size of that Window) is it not appropriate to write something like

Var widthOfParentWindow As Integer
widthOfParentWindow = Me.Window.Width

Or is it preferable to write

Var widthOfParentWindow As Integer
widthOfParentWindow = Self.Window.Width

For some reason, I am concerned that the Self will cause “confusion” when the code is actually being run as a method in a control that lives in a Window.

The example in the Documentation for DesktopControl.Window is:

This code gets the parent window’s Title property.

MessageBox(Me.Window.Title)

So Me is being used here in this example. Would this better have been written

MessageBox(Self.Window.Title)

??

Self would be correct. Because it’s a subclass, this bit applies:

When working with classes and subclasses you have added to your project, you should always use Self (or nothing since Self is the default).

If we had a time machine, I’d argue that Me should only be added to event handlers of classes placed on a window. But that ship has sailed. Even with all the API2 changes, that would break too much code.

2 Likes

It helps me to remember that while writing (sub)class code, all there is to a subclass is itSelf. When writing instance (event handler) code, the instance is aware of its parent (window, page, view …), so it can distinguish between itself as being “Me” while being part of the bigger picture – “Self”.

Philosophically of course this brings up interesting concepts.
If Self <> Me Then :crazy_face:

4 Likes

I use the opposite approach. I always use Me, because it always refers to the control. Self can refer to the control or the window, depending on context. I find it much safer to use Me. I very rarely use Self and only in situations where it is clear that it refers to the window, not the control.

5 Likes

I can see this logic, but the documentation takes the other tack. I have a communication with Geoff which I would interpret as leaning toward your (Tim’s) preference. I guess there are two correct ways of thinking about this. My personality type is one that does not like this.

Well, valid in the sense that it works as a reference to the invoker object, yes. Should be used? I would avoid it and use self, that retains THE SAME value as self in this context, as the usual way it is used in other languages.
A “ME” (or sender, instance of the object in the context invoking an event) reference floating around does not exist in other languages. Other languages usually passes the reference of the instance being handled by a event listener in the parameter list, usually people call it “sender”, the object who is sending this event to be processed. ME is the sender here, but weirdly, it does not exist only and is sent to event handlers when needed, it exists floating around and causing confusion, and that’s why we should avoid it.
So, I would use self everywhere (in some languages it would be “this” (self or this) for the current instance), and ME only when I do expect a “sender”.
This help me keeping a common core in my mind while hopping around through multiple languages.

1 Like

So Self always points to the class. A window is a class. If it wasn’t for controls, Me wouldn’t have a reason to exist at all. It is the interloper here. So much so, that the IDE is the one that injects it into each method.

A control on a window is just a property. Its event handlers are just methods. I don’t mean this figuratively, this is literally how the IDE builds them. A PushButton’s Pressed event looks something like:

Private Sub MyPushButton_Pressed(Sender As PushButton)
  Const CurrentMethodName = “Window1.MyPushButton.Pressed”
  Var Me As PushButton = Sender

  // Your code
End Sub

Oh look, there’s the sender that Rick was talking about. When I was working on the IDE, the sender wasn’t there and Me was assigned to the window’s property, like Var Me As PushButton = Self.MyPushButton but I believe they use AddHandler these days. It doesn’t make much difference to the conversation.

The fact that Me changes context is why it isn’t recommended. Self always means the class. Me could mean the class or the control.

I used to do the same, preferring Me over Self. Once I learned what is going on behind the scenes, I pretty much stopped using Me. Except in control event handlers of course.

I do wish we had something like Static that would refer to the class or module, as we don’t have a good way to refer to those in shared code. If I’m in a shared or module method, I don’t have any sort of prefix - besides the object’s name - to use. So I either write ambiguous code, or hard code the name. Neither is particularly great, but not very problematic either. Just kind of annoying.

3 Likes