gpt4 book ai didi

ruby - 为什么Ruby setter在类(class)中需要“ self ”资格?

转载 作者:太空宇宙 更新时间:2023-11-03 16:41:10 24 4
gpt4 key购买 nike

无论是由(c)attr_accessor创建还是手动创建的ruby setter似乎是在类本身中访问时需要self.限定的唯一方法。这似乎把Ruby单独放在了语言的世界里:
所有方法都需要self/this(比如perl,我认为javascript)
没有方法需要self/thisis(c,java)
只有setter需要self/this(红宝石?)
最好的比较是c与ruby,因为这两种语言都支持访问器方法,它们的语法工作方式与类实例变量一样:foo.x = yy = 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方法的情况?
当然,在很多情况下,自我变得必不可少这并不是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

这是一个方法调用还是一个新的局部变量赋值?
@迈克·斯通
你好!我理解并感谢你的观点
很好的例子相信我,如果我有足够的名声,
我会投票决定你的答复。但我们仍然不同意:
关于语义的问题
论事实的中心点
首先,我声明,并非没有讽刺意味,我们正在就
“歧义”的含义。
当涉及到解析和编程语言语义(主题
在这个问题上),你肯定会承认一个广泛的概念
“模棱两可”。让我们采用一些随机符号:
歧义:词汇歧义(Lax必须“向前看”)
歧义:语法歧义(yacc必须服从解析树分析)
模棱两可:模棱两可知道执行时的一切
(2-3之间也有垃圾)。所有这些类别都由
收集更多的上下文信息,越来越全球化。所以当你
说,
“qwerty=4”在c中是明确的#
当没有定义变量时…
我完全同意。但出于同样的原因,我是说
“qwerty=4”在ruby中不含糊
(就像现在一样)
“qwerty=4”在C中不明确#
我们还没有互相矛盾。最后,我们真的
不同意:ruby在没有任何进一步的
语言的结构是这样的,
对于“qwerty=4”,ruby毫不含糊
如果存在,调用现有的设置程序。
没有定义局部变量
你说不,我说是的,另一个红宝石可以存在,它的行为完全相似。
除了“qwerty=4”之外,电流在各个方面都定义了一个新的
变量在没有设置器和没有本地存在时,调用SET
存在,并且如果存在,则将其赋值给局部。我完全接受
可能是错的。事实上,我可能错的一个原因很有趣。
让我解释一下。
假设您正在使用访问器方法编写一种新的OO语言
like instances变量(比如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也可以这么做,但是'later'必须在运行时,因为
正如本指出的,直到语句被执行,你才知道是哪种情况
应用。
我的问题从来不是想说“我真的需要‘自我’?”或者“什么”
避免了潜在的歧义?”我倒是想知道为什么
做出特定选择也许这不是表演。也许它刚得到这份工作
完成,或者认为最好总是允许一个1行本地重写
方法(非常罕见的情况要求)。。。
但我想说最有活力的语言可能是
将此决定推迟最长时间,并基于最上下文选择语义
信息:所以如果你没有本地的并且你定义了一个setter,它将使用setter。不是
这就是为什么我们喜欢ruby,smalltalk,objc,因为方法调用是在运行时决定的,
提供最大的表现力?

最佳答案

这里要记住的重要一点是,Ruby方法可以在任何时候被(取消)定义,因此为了智能地解决这种模糊性,每个赋值都需要运行代码来检查在赋值时是否有一个具有赋值给名称的方法。

关于ruby - 为什么Ruby setter在类(class)中需要“ self ”资格?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49503137/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com