Ruby setters–是否由
(c)attr_accessor
或者手动检测是唯一需要的方法
self.
在类本身中访问时的限定。这似乎让Ruby在语言世界中独占鳌头:
-
所有方法都需要
self
/
this
-
不需要任何方法
这
-
只有二传手需要
自己
/
这
最好的比较是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();
}
}
问:这是真的吗?除了二传,还有其他需要自我的场合吗?也就是说,是否有其他情况下使用Ruby方法
不能
没有
自己
当然,在很多情况下,自我保护
必需的这并不是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
}
}
同样的歧义也是以同样的方式解决的。但我想问的是这个案子在哪里
我们遇到
qwerty = 4
这是一个方法调用还是一个新的局部变量赋值?
@迈克·斯通
你好我理解并赞赏你提出的观点和你的建议
榜样是伟大的。相信我,如果我有足够的声誉,
我赞成你的回答。但我们仍然不同意:
首先,我要说的是,我们正在就
“歧义”的含义。
当涉及到解析和编程语言语义时(主题
关于这个问题),你肯定会承认这个概念的广泛性
“歧义”。让我们采用一些随机符号:
-
-
歧义:语法歧义(yacc必须遵循解析树分析)
-
模棱两可:模棱两可,在执行时知道一切
(2-3之间也有垃圾)。所有这些类别都由
说
“qwerty=4”在C中是明确的#
“qwerty=4”在ruby中没有歧义
(目前的情况)
“qwerty=4”在C中是不明确的#
我们还没有互相矛盾。最后,这里是我们真正需要的地方
不同意:如果没有进一步的改进,ruby可能实现,也可能无法实现
语言的结构是这样的,
对于“qwerty=4”,ruby明确表示
如果存在,则调用现有的setter
没有定义局部变量
你说不,我说是;另一个ruby可能存在,其行为与
当前各方面,,
除了
“qwerty=4”定义了一个新的
存在,如果存在,则分配给本地。我完全接受我
可能是错的。事实上,我可能错的一个原因很有趣。
让我解释一下。
假设您正在编写一种具有访问器方法的新OO语言
比如实例vars(比如ruby&C#)。你可能会从
概念语法类似于:
var = expr // assignment
method = expr // setter method invocation
但是解析器编译器(甚至不是运行时)会呕吐,因为即使在
你面临着一个经典的选择。我不能确定细节,但是
ruby基本上做到了这一点:
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也可以这样做,但是“以后”必须在运行时,因为
正如ben指出的,在执行语句之前,您不知道是哪种情况
应用。
我的问题从来不是要问“我真的需要‘自我’?”或“什么?”
我想知道为什么会这样
有什么特别的选择吗?也许这不是表演。也许它刚得到这份工作
完成,或者认为最好始终允许1-liner local覆盖
但我想说的是,最有活力的语言可能是
延迟此决定的时间最长,并根据最上下文的上下文选择语义
信息:因此,如果您没有本地设置,并且您定义了一个setter,那么它将使用setter。不是吗
这就是为什么我们喜欢ruby、smalltalk和objc,因为方法调用是在运行时决定的,
提供最大的表现力?