Ruby setter无论是由(c)attr_accessor
创建的还是手动创建的,似乎是在类本身中访问时唯一需要self.
限定的方法.这似乎让Ruby在语言世界中独占鳌头:
- 所有方法都需要
self
/this
(比如Perl,我认为Javascript) - 没有方法需要
self
/this
is(C#,Java) - 只有二传手需要
self
/this
(Ruby ?)
最好的比较是C#和Ruby,因为这两种语言都支持访问器方法,它们在语法上就像类实例变量:foo.x = y
y = foo.x
.C#称之为属性.
这里有一个简单的例子;Ruby和C#中的相同程序:
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
拿走self.qwerty =()
,它就会失败(Linux和OS X上的Ruby 1.8.6).现在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();
}
}
问题:这是真的吗?除了二传,还有其他需要self 的场合吗?也就是说,在其他情况下是否会调用Ruby方法cannot?
当然,在很多情况下,self 保护是必要的.这并不是Ruby独有的,只是要明确一点:
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
}
}
同样的歧义也会以同样的方式解决.但我想问的是这个案子
- 已定义方法has,以及
- 已定义No个局部变量,并且
我们遇到
qwerty = 4
这是一个方法调用还是一个新的局部变量赋值?
@迈克·斯通
你好我理解并感谢你所提出的观点和你的建议
- 在语义问题上,以及
- 在一个中心事实上
首先,我要说的是,我们正在就
当涉及到语法分析和编程语言语义(主题
- 歧义:词汇歧义(lex必须"向前看")
- 歧义:语法歧义(yacc必须遵循解析树分析)
- 模棱两可:模棱两可,在执行时知道一切
(2-3之间也有垃圾).所有这些类别都由
"qwerty=4"在C中是明确的#
我完全同意.但出于同样的原因,我要说
"qwerty=4"在ruby中没有歧义
"qwerty=4"在C中是不明确的#
我们还没有相互矛盾.最后,这里是我们真正的
对于"qwerty=4",ruby明确表示
你说不,我说是;另一个ruby可能存在,其行为与
让我解释一下.
想象一下,您正在编写一种带有访问器方法的新OO语言
var = expr // assignment
method = expr // setter method invocation
但是解析器编译器(甚至不是运行时)会呕吐,因为即使在
var = expr // assignment (new or existing)
// method = expr, disallow setter method invocation without .
这就是为什么它是不含糊的,而C#是这样做的:
symbol = expr // push 'symbol=' onto parse tree and decide later
// if local variable is def'd somewhere in scope: assignment
// else if a setter is def'd in scope: invocation
对于C#,"later"仍处于编译时.
我相信ruby也可以这样做,但是"以后"必须在运行时,因为
我的问题从来不是想说"我真的需要‘self ’?"或者"什么
但我想说的是,最有活力的语言可能就是