Ruby setters -- whether created by (c)attr_accessor or manually -- seem to be the only methods that need "self." qualification when accessed within the class itself. This seems to put Ruby alone the world of languages:
- all methods need self/this (like perl, and I think Javascript)
- no methods require self/this is (C#, Java)
- only setters need self/this (ruby??)
The best comparison is C# vs ruby, because both languages support accessor methods which work syntactically just like class instance variables: foo.x = y, y = foo.x . C# calls them properties.
Here's a simple example; the same program in ruby then C#
#!/usr/bin/ruby
class A
def qwerty; @q; end # manual getter
def qwerty=(value); @q = value; end # manual setter, but attr_accessor is same
def asdf; self.qwerty = 4; end # "self." is necessary in ruby?
def xxx; asdf; end # we can invoke nonsetters w/o "self."
def dump; puts "qwerty = #{qwerty}"; end
end
a = A.new
a.xxx
a.dump
take away the self.qwerty =() and it fails (ruby 1.8.6 on linux & osx). Now C#,
using System;
public class A {
public A() {}
int q;
public int qwerty {
get { return q; }
set { q = value; }
}
public void asdf() { qwerty = 4; } // C# setters work w/o "this."
public void xxx() { asdf(); } // are just like other methods
public void dump() { Console.WriteLine("qwerty = {0}", qwerty); }
}
public class Test {
public static void Main() {
A a = new A();
a.xxx();
a.dump();
}
}
Question: Is this true? Are there other occasions besides setters where self is necessary?
UPDATE:
Thanks all for the feedback. First let me be more precise about the concluding question.
Question at Bottom: Are there other occasions where a ruby method cannot be invoked without self?
I agree, there are lots of cases where self becomes necessary. This is not unique to ruby, just to be clear:
using System;
public class A {
public A() {}
public int test { get { return 4; }}
public int useVariable() {
int test = 5;
return test;
}
public int useMethod() {
int test = 5;
return this.test;
}
}
public class Test {
public static void Main() {
A a = new A();
Console.WriteLine("{0}", a.useVariable()); // prints 5
Console.WriteLine("{0}", a.useMethod()); // prints 4
}
}
Same ambiguity is resolved in same way. But while subtle I'm asking about the case where
- A method has been defined, and
- No local variable has been defined, and
we encounter
qwerty = 4
Ambiguity: Is this a method invocation or an new local variable assignment?
The title question as to why ruby always treats this as an assignment, is perhaps best answered by ben. Let me paraphrase
Summary: The parser could treat "symbol =" as an lvalue and dynamically decide between assignment and invocation. The dynamic nature of ruby means every assignment potentially faces this ambiguity, so in the interest of performance, ruby treats this as assignment always. C# benefits from knowing what all the methods are, and treats this case the opposite way (as a method invocation).