Ruby 为什么可以';我不能改变自我的价值吗?

Ruby 为什么可以';我不能改变自我的价值吗?,ruby,self,Ruby,Self,为什么我可以这样改变“自我”: self.map! {|x| x*2} self.replace(self.map {|x| x*2}) self = self.map {|x| x*2} 或者这样: self.map! {|x| x*2} self.replace(self.map {|x| x*2}) self = self.map {|x| x*2} 但不是这样: self.map! {|x| x*2} self.replace(self.map {|x| x*2}) se

为什么我可以这样改变“自我”:

self.map! {|x| x*2}
self.replace(self.map {|x| x*2})
self = self.map {|x| x*2}
或者这样:

self.map! {|x| x*2}
self.replace(self.map {|x| x*2})
self = self.map {|x| x*2}
但不是这样:

self.map! {|x| x*2}
self.replace(self.map {|x| x*2})
self = self.map {|x| x*2}

为什么Ruby不允许我更改“self”变量指向的对象,但允许我更改对象的属性?

不是答案,只是一个线索

a=[1,2]
=>[1,2]
a.object_id
=>2938

a.map!{|x| x*2}
=>[2,4]
a.object_id  # different data but still the same object
=>2938

a.replace(a.map {|x| x*2})
=>[4,8]
a.object_id  # different data but still the same object
=>2938

a = a.map{|x| x*2} # .map will create a new object assign to a 
=>[8,16]
a.object_id  #different object
=>2940   

在Ruby中,值和变量是引用(指向对象的指针)。赋值给一个变量只是让它指向一个不同的对象;它对变量所指向的对象没有影响。要更改对象,必须对其调用方法(包括属性getter/setter)


您可以将
self
视为一个变量,它指向调用该方法的对象。如果可以指定给它,可以使它指向另一个对象。如果你能做到这一点,它就不会改变调用该方法的对象;相反,您可以使该方法中使用
self
的任何后续代码都使用该对象,而不是调用该方法的对象。这将是非常令人困惑的,因为
self
将不再指向调用该方法的对象,这是一个基本假设。

我的猜测是,前两个选项只替换值/属性,而第三个选项实际上可以替换对象本身(您不想要)。这并不难,这是不可能的。谢谢你,这太好了。帮我澄清我的问题!谢谢你的回复!你的答案似乎是Ruby不允许这样做,因为这会让人困惑/不好的做法。但是Ruby允许很多令人困惑/不好的做法。那么为什么不允许这一个,而允许其他的呢?而且,我所知道的每一种语言都不允许这样做。因此,问题似乎比仅仅糟糕的实践/混乱更严重。@user3680688:不仅仅是Ruby。几乎所有面向对象的语言都不允许将变量
分配给this
/
self
。此外,99%的人认为他们想要分配给
self
,这是因为他们不知何故错误地认为这会改变调用该方法的对象。但在Ruby中,赋值给变量并不是这样做的。它只是让变量指向一个不同的对象,“而且,我所知道的每种语言都不允许这样做”。我意识到不仅仅是鲁比。我感谢你花时间回答,但你没有回答我的问题。我承认想要改变自我的价值是不好的做法。但为什么所有这些语言都让这种糟糕的做法变得不可能呢?为什么是这个?当许许多多其他的不良行为被允许的时候。您的解释似乎遗漏了一些内容。@user3680688:1)因为它很可能会被大多数遇到它的人误解,您会在这样的网站上看到大量问题,询问他们为什么分配给self,而self不会改变对象。2) 因为
self
不是一个通用变量;它只是一个定义非常明确的隐式变量(它指向调用该方法的对象),如果您可以分配给它,您将破坏它。@user3680688:3)如果您可以使
self
指向另一个对象,并且您访问一个实例变量或实例方法(不显式调用对象),我甚至不知道它是否会使用调用该方法的对象或新的
self
;如果它使用新的
self
,这将打破不能从另一个对象访问实例变量的规则。