Some object-oriented languages require you to put "self.", or equivalent, in front of all methods and/or member accesses. This makes ExtractMethod''''''s painful, while encouraging warts such as ForeignMethod''''''s and Static Methods. ''These are controversial. Besides, if these were the only problems with explicit self, I think the enhanced readability (see below) will weigh more.'' Languages guilty of requiring self-dot prefixes on methods only: * SmalltalkLanguage ** This is how Smalltalk disambiguates (at the grammar level) between a unary message selector and an attribute (data member) access. "foo" within a method, if it doesn't refer to a local, refers to a data member and never a method; "self foo" means "call send the message foo to me, with no arguments". In other words, self serves the same purpose (among other things) that () does in other languages. ** ''It should be noted as well that Smalltalk allows attributes (data members) to have the same name as unary message selectors (keyword message selectors have colons in the name). It's a common idiom to have accessor methods have the same name as the corresponding attribute, and mutators have the same name plus a colon.'' Languages guilty of requiring prefixes on member access: * RubyLanguage (sort of -- it requires an @) (See TheProblemWithSigils) ** It's more complex than that: You can set an accessor to provide external access to a member variable, and then member methods can access the same variable either with or without the @. Yes, this does confuse some beginners. *** Just to be more specific, in Ruby, member methods can have only read access to the same variable either with or without the @. If you want to assign a value (i.e write access), then you have to use self.variable = or @variable = Languages guilty of... egads!... both: * PythonLanguage - self isn't even implied. * PerlLanguage - And an ugly one at that: $self->method() and $self->{member}. $self isn't implied, either! * PhpLanguage - Also ugly: $this->method() and $this->member, but at least $this is implied * LingoLanguage - As soon as you use inheritance, you have to write a me.method or me.property. Languages that don't require either: * C++ * Java * C# * Delphi * Eiffel * Self * E ''The first five are statically-typed languages without delegation; for any unqualified variable (not on the right-hand side of a . or ->) the compiler can unambiguously determine to what scope it ought to belong to (and terminate with an error if the answer is "none" [or "more than one"]). When you start throwing delegation into the mix, life becomes a bit harder--SelfDotSyndrome is a way of making sure things are unambiguous.'' ---- At least in PythonLanguage, where used to be only three scopes (global, module, and method/function), I think the explicit markup for calling self's methods is a big pro. One seldom puts anything except class and function definitions in the global / module namespaces, so actually we only have one namespace, the local namespace. This improves readability a lot. Furthermore, I'm still surprised how few people realise that you don't have to call it "self": "s" is just as good if you use it consistently. * people does not realize that because they will be flamed to death on comp.lang.python if they ever do such a stupid thing as to name "self" something else (except for (meta)class methods) Even further, having same syntax for calling other objects' methods and calling your own methods has the nice effect that you often start to think what kind of interface the class provides for itself or its descendants, which eventually evolves into having a well-defined set of minimum functionality in the object and reducing possibility of leaving the object temporarily with a broken invariant. ---- ''These are statically typed languages. That's how they get by without SelfDotSyndrome. Their compilers have a lot more information available to them at compile time, which they use to resolve members and methods.'' The SelfLanguage is like this too, even though it's dynamically typed. It can do this because it does away with the difference between member access and method invocation - when you send a message to an object, that message can invoke either a data slot or a method slot. ''Self is an interesting case. It uses its scoping rules to resolve method and member access (which, as is pointed out above, always look like method invocations), and the parent scope of a method is always the object to which it is attached. This isn't so in Python, which traditionally has only method scope and global scope. Perl's scoping rules are too weird to even contemplate, and so-called "members" in Perl aren't even variables and are thus not part of ''any'' scope. Someone please fill in details on Ruby's scoping and how it contributes to Ruby's SelfDotSyndrome.'' It should be just ''.member''. Except the '.' is harder to see than Ruby'''''s '@'. And that should only be when you need a local variable with the same name as the instance variable (useful in setter/initialization methods for readability)--otherwise, scoping should be implicit. ''This stuff about static vs. dynamic and scoping rules is kind of pointless. I suppose I'm trying to understand why these languages use this particular design.'' EeLanguage uses SoftTyping, so type information is not necessarily available. It is an interesting case because its avoidance of SelfDotSyndrome is purely a consequence of LexicalScoping: a method is just a function definition that captures the state of the object as part of the lexical context. ---- Explicit self is not all bad. Having self explicit makes creating wrappers a lot easier. ''What sort of wrapper?'' One way to modify an object's behavior is to surrounding it with a "wrapper" object. The wrapper object receives messages, responds to the ones it wants to, and passes the rest to the "wrappee" object. aRedButton wraps aButton aRedButton receives #size message, and passes it to aButton aRedButton receives #color message, and returns "red" But what if #size depends on #color? When the wrappee (aButton) sends a message to self, such as self.color, you want self to be the wrapper (aRedButton), to continue catching desired messages. Easy in Python, hard in Smalltalk. Wrappers are used a lot in the VisualWorks GUI classes. Used too much, in some peoples' opinion. ---- Maybe I'm becoming a Ruby zombie, but I like the way Ruby does it -- no differentiation for methods, but the @ prefix for instance variables. (And @@ for class variables, too.) As I wrote over in RubyLanguage, I've used this to help me figure out where a class is coupled, which can give you quick guidance during refactoring. -- francis But that's TheProblemWithSigils. People think they like them, even though they could simulate them. ''Well, not exactly. Most languages won't let you start a symbol name with a non alphanumeric character like "@". You can assign your own house style -- "All instance variables need to start with the letters 'cv_'" or whatever -- but the ampersand's a little more concise, and if you don't have the symbol overload you have with Perl it can actually make things easier.'' ---- Because CeePlusPlus does not require self, there is a danger of namespaces getting confused: static int table[] = {1,2,3}; // global var int Some''''''Class::memfunc(int x) { return table[x] * datamember.size() } Here a member function of Some''''''Class is accessing a table which is in global space (though local to the source file). Now, suppose somebody adds a member 'table' to Some''''''Class, or one of its public bases. Now, the 'table' refers to a class member, not the global! This risk, I think, is one of the reasons for practices like starting all member names with 'm_' (which is basically forcing SelfDotSyndrome on oneself, cluttering up not only the code but the class definition). Another fix is to use return ::table[x]; // Reverse SelfDotSyndrome!! but are you going to put these :: in front of all globals? In practice, this problem rarely pops up, maybe because globals are rare, and most programmers start global names in uppercase and member names in lower case. But it could take a while to track down when it does pop up, since the true cause is so unexpected. Clearly, the reason for addition of the 'table' member may be completely unrelated to the 'memfunc' method (which could be in a derived class!); the programmer would not expect a change in the function of memfunc() due to this change. FWIW, there is a similar gotcha in Pascal, related to 'with XX do' (or however it's phrased). ----- Would somebody care to supply a realistic example that demonstrates how "self" (or "self." or "$self->") interferes with refactoring? I've refactored in Smalltalk, C++, and Perl, and I don't resonate with the problem that SelfDotSyndrome alludes to. But then perhaps I missed something. -- DaveSmith I actually don't think that the "eases refactoring" reason is particularly true. Here's the only kind of example I can think of: area | width. height | width: right - left. height: bottom - top. width * height refactors to: width right - left height bottom - top area width * height Not a particularly good example (does anybody have a better one?), but I do think that the SelfLanguage's lack of SelfDotSyndrome helped very slightly, in a couple of ways: * I switched "width" and "height" from being local variables to being methods, without needing to change the "width * height" line at all. * If I ever decide that "width" and "height" should be instance variables instead of methods, I still won't have to change the "width * height" line. (This is only related to the SelfDotSyndrome in languages like Smalltalk, because the presence of the word "self" is how Smalltalk disambiguates between instance variable accesses and method calls. Much better to just stop disambiguating.) I do think that the above code would look a whole lot uglier if I had to write the word "self" all over it, which is the main reason why I don't like SelfDotSyndrome. The code is perfectly clear without the "self", somewhat more flexible, and somewhat less cluttered. -- AdamSpitz ---- When you start out with functions and later realize that it would be better to use classes, the explicit "self" complicates refactoring. You have to insert "self" as the first parameter of each function that becomes a method, and you have to make sure that each class attribute "x" is replaced by "self.x". Here's a (very simplistic) example: I have a constant and define functions for adding to and removing from the constant. a = 0 def add(b): return a + b def sub(b): return a - b Later, I'd like to wrap this functionality into a class: class C: def __init__(self, a): self.a = a def add(self, b): return self.a + b def sub(self, b): return self.a - b I use this kind of refactoring quite often. -- AlbertBrandl ---- In JavaLanguage, I use the convention of prefixing instance attributes with an underscore: public class C { private int _a; public C( int a ) { _a = a; } public add( int b ) { _a += b; } } In PythonLanguage, I use the underscore instead of the word "self": class C: def __init__( _, a ): _.a = a def add( _, b ): _.a += b That's a personal preference, of course, and not the standard pythonic way of doing things. But people who find "self" a bit distracting when written out might find it helpful, hopefully. -- FalkBruegmann On the other hand, people experienced with SML/NJ, Haskell, EeLanguage or ErlangLanguage are going to have a hard time figuring out why you keep referring to the "never mind" variable... In the PythonInterpreter, the global '_' stores the last value returned: >>> 'foo' 'foo' >>> _ + 'bar' 'foobar' ---- The habitual use of read & write accessors in Smalltalk resolves the SelfDotSyndrome in a way that makes refactoring simple. If instance variable access only in a getter/setter, then we have (using Point and Rectangle) '''left''' ^self origin x '''right''' ^self corner x '''top''' ^self origin y '''bottom''' ^self corner y '''width''' ^self right - self left '''height''' ^self bottom - self top '''area''' ^self width * self height In order to * Make width and height local variables, change the #width and #height methods as follows: '''width''' ^width '''height''' ^height : No other changes are needed. * To switch back in EnvyDeveloper (the only environment I'll use), simply revert #width and #height to their earlier edition. In NewLisp, you must use `(self)`: (define (Circle:area ) (mul (:radius (self)) (:radius (self)) 3.141592))