Ruby setter(無論是由(c)attr_accessor
創建的還是手動創建的)似乎是在類自身內部進行訪問時唯一需要self.
限定的方法。這似乎把紅寶石單獨的語言世界:爲什麼Ruby制定者需要「自我」。在課堂上的資格?
- 所有方法都需要
self
/this
(如Perl,我認爲JavaScript)的 - 沒有方法需要
self
/this
是(C#,Java的) - 只有制定者需要
self
/this
(紅寶石?)
最好的比較是C#VS紅寶石,因爲這兩種語言都支持這句法工作就像類斯塔存取方法nce變量:foo.x = y
,y = foo.x
。 C#調用它們的屬性。
下面是一個簡單的例子;在紅寶石同一程序然後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 =()
和失敗(紅寶石1.8.6在Linux & OS X)。現在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
這是模棱兩可的 - 這是一個方法調用還是一個新的局部變量賦值?
@Mike石
嗨!我理解並欣賞您提出的觀點,並且您的示例很棒。相信我,當我說,如果我有足夠的聲譽, 我會投你的迴應。然而,我們仍然不同意:
- 語義上的問題,並在事實上
首先我要求,不無諷刺,我們具有關於語義爭論的中心點
當談到解析和編程語言語義(這個問題的主題 ),當然你會承認廣泛的概念 '歧義'。讓我們只採用一些隨機的符號:
- 曖昧:詞彙歧義(法必須「向前看」)
- 曖昧:歧義(YACC必須按照解析樹分析)
- 含糊:歧義知道一切在執行的時刻
(並且在2-3之間也有垃圾)。所有這些類別均由 解決,收集更多上下文信息,在全球範圍內看起來越來越多。所以,當你 說,
「QWERTY = 4」 是在C# 明確的時候沒有定義的變量...
我不能同意。但是,同樣的道理,我說
「QWERTY = 4」 是紅寶石 未明確(因爲它現在已經存在)
「QWERTY = 4」 是在C#不明確
而且我們還沒有相互矛盾。最後,這就是我們真正 不同意:無論是紅寶石可以或不可以在沒有任何進一步的 語言結構實現,這樣,
對於「QWERTY = 4,」紅寶石明確 調用現有的二傳手,如果有
是沒有定義的局部變量
你說不。我說是;另一個紅寶石可能存在,其行爲與 完全相同,除外「qwerty = 4」定義了一個新的 變量,當沒有setter和本地存在時,它調用setter,如果一個 存在,並且它分配給本地(如果存在)。我完全同意我可能是錯誤的 。事實上,我可能會犯錯的原因很有意思。
讓我解釋一下。
想象一下,您正在編寫一個新的面向對象方法,使用像實例變量(如ruby & C#)的 。你可能有 概念語法像開始:
var = expr // assignment
method = expr // setter method invocation
但是解析器編譯器(甚至不運行時)會吐的,因爲即使在 所有的輸入grokked有沒有辦法知道哪些語法相關。 您正面臨着哪一個經典選擇。我不能肯定的細節,但 基本上紅寶石做到這一點:
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#,「以後'仍在編譯時。
我敢肯定,紅寶石可以做同樣的事情,但'稍後'必須在運行時,因爲 明確指出,你不知道,直到執行聲明 適用。
我的問題從來沒有打算表示「我真的需要'自我'嗎?」?或「什麼 潛在的歧義正在被避免?」相反,我想知道爲什麼這個 做出了特別的選擇?也許這不是性能。也許它只是完成了 的工作,或者它被認爲是最好的總是允許1班輪本地覆蓋 方法(一個非常罕見的情況下要求)...
但我有點暗示,最動態的語言可能是 推遲這個決定的時間最長的語言,並且選擇基於最上下文 信息的語義:所以如果你沒有本地並且你定義了一個setter,它會使用setter。這不是 這就是爲什麼我們喜歡ruby,smalltalk,objc,因爲方法調用在運行時決定, 提供最大的表現力?
PHP在訪問實例變量時也需要`$ this->`。這讓我一直在旅行。 – Chloe 2014-01-01 23:50:55
只有類方法需要顯式接收器,而不是實例方法。 – 2014-10-01 23:52:17
我同意 - 我也不喜歡這種解決amibuity的方法。違反最少驚喜的原則。 – Dogweather 2016-01-17 22:14:18