Ruby 可以将对象更改为其他类的实例吗?
方法接收的参数是对与传递给它的参数相同的对象的引用,例如:Ruby 可以将对象更改为其他类的实例吗?,ruby,Ruby,方法接收的参数是对与传递给它的参数相同的对象的引用,例如: def object_id_of_param(object) object.object_id end the_object = [1, 2, 3] the_object.object_id # => 15247020 object_id_of_param(the_object) # => 15247020 如果调用该对象的实例方法,从对该对象的任何引用就地修改该对象,而不考虑范围,则所有变量引
def object_id_of_param(object)
object.object_id
end
the_object = [1, 2, 3]
the_object.object_id # => 15247020
object_id_of_param(the_object) # => 15247020
如果调用该对象的实例方法,从对该对象的任何引用就地修改该对象,而不考虑范围,则所有变量引用的单个对象本身会就地修改,例如:
def modify_object(object)
object.map! { |n| n + 1 }
end
the_object = [1, 2, 3]
the_object.object_id # => 18047480
the_object # => [1, 2, 3]
modify_object(the_object)
the_object.object_id # => 18047480
the_object.inspect #=> [2, 3, 4]
如果您想对该对象和类似Array#map的方法执行其他操作代码>不可用,您可以使用Object@instance_variable_set
更改它(请参阅)
如果您试图将其完全更改为另一个类,它将不起作用;以下方法不会修改原始对象。它不会将它从数组
转换为时间
;它使方法中的新对象
变量引用新的时间
对象:
def fail_to_modify_object(object)
object = Time.now
end
the_object = [1, 2, 3]
the_object.object_id # => 14554660
the_object.inspect #=> [1, 2, 3]
fail_to_modify_object(the_object)
the_object.object_id # => 14554660
the_object.inspect #=> [1, 2, 3]
将一个数组
对象转换为一个新的时间
的示例是人为设计的,但是您得到了这个想法
是否可以将一个由任意数量的变量引用的对象更改为另一个类的实例?Bang方法不一定总是就地修改对象
爆炸只是一种惯例,它说这种方法比没有爆炸的方法“更危险”。例如,在rails中,许多bang方法会引发异常,而不是返回nil
此外,方法没有爆炸的事实并不意味着它不修改对象(例如)
关于如何修改不提供任何变异方法的对象,您可以使用和:
但是,请注意,如果某人没有给您直接访问某个对象的权限,99.99%的情况下,如果您试图访问某个对象,您会犯错误。要修改保留其标识(对象id)的对象,新对象必须至少与以前属于同一类;否则,它就没有意义了。无法将时间
实例修改为数组
实例,反之亦然,无法保留其标识
或者,如果您在第二个示例中的意思是简单地将\u对象
的引用从时间
实例更改为数组
实例,那么这是局部变量的范围问题,与不变性无关。您需要区分变量和对象
在方法中,您可以访问对象。您无法访问在方法外部定义的变量
如果写入object=Time.now
,则不会更改对象,而是将另一个对象指定给变量object
。旧对象仍然存在。
方法之外的变量仍然保存旧对象
您可以通过向对象发送消息来更改对象。如果你有一个数组对象,你可以在这里看到你的变量方法:有些方法改变数组,有些方法只是返回一些东西
您可以执行诸如对象[0]=时间之类的操作。现在
。甚至这也被实现为对[]=
的方法调用。它会将数组对象的第一个元素更改为现在保存时间对象。因此,您可以非常自由地更改数组对象
如果您是高级的,甚至可以向数组对象添加新方法,使其行为类似于时间对象。但这几乎总是不是一个好主意
变量仅存在于定义的位置 凉爽;这可用于以比现有实现更多的方式就地修改对象。我更想知道是否有可能以真正任意的方式更改对象,比如像示例中那样使它们成为一个完全不同的类的实例。但是,如果可能的话,如何使用、应该使用和不应该使用与问题无关。问题不在于更改范围外变量引用的对象,而在于是否可能以任意方式更改任意数量变量引用的对象(如将数组更改为时间)如果给定其中一个变量。就地更改对象的实例方法可以做到这一点,更改实例变量也可以做到这一点,但您的更改范围有限
class X
attr_reader :foo
def initialize
@foo = :bar
end
end
x = X.new
x.foo # => :bar
x.instance_variable_set(:@foo, :baz)
x.foo # => :baz