Ruby是按引用传递还是按值传递?

Ruby是按引用传递还是按值传递?

@user.update_languages(params[:language][:language1], 
                       params[:language][:language2], 
                       params[:language][:language3])lang_errors = @user.errors
logger.debug "--------------------LANG_ERRORS----------101-------------" 
                + lang_errors.full_messages.inspectif params[:user]
  @user.state = params[:user][:state]
  success = success & @user.saveendlogger.debug "--------------------LANG_ERRORS-------------102----------" 
                + lang_errors.full_messages.inspectif lang_errors.full_messages.empty?

@user对象将错误添加到lang_errors变量中的update_lanugages方法。当我对@user对象丢失最初存储在lang_errors变量。

虽然我试图做的更多的是一次黑客攻击(这似乎不起作用)。我想了解为什么变量值会被淘汰。我理解引用传递,所以我想知道如何在不被淘汰的情况下将值保存在变量中。


温温酱
浏览 478回答 3
3回答

慕容708150

在传统术语中,Ruby严格按值传递。..但这不是你想要的。Ruby没有任何纯、非引用值的概念,因此您当然不能将其传递给方法。变量总是引用对象。为了获得一个不会在您下面更改的对象,您需要使用DUP或克隆所传递的对象,从而给出一个没有其他人引用的对象。(尽管如此,这并不是防弹的-这两种标准的克隆方法都是浅拷贝的,因此克隆的实例变量仍然指向与原始对象相同的对象。如果象牙引用的对象发生了变异,那么它仍然会出现在副本中,因为它引用的是相同的对象。)

蝴蝶刀刀

其他答案都是正确的,但一位朋友要求我向他解释这一点,其实质在于Ruby是如何处理变量的,因此我想分享一下我为他写的一些简单的图片/解释(为篇幅而道歉,可能有些过于简单化):Q1:当你给一个新变量赋值时会发生什么?str值为.'foo'?str = 'foo'str.object_id # => 2000A:一个叫做str创建指向对象的'foo',对于这个Ruby解释器的状态,它恰好位于内存位置。2000.Q2:赋值现有变量时会发生什么?str使用=?str = 'bar'.tap{|b| puts "bar: #{b.object_id}"} # bar: 2002str.object_id # => 2002A:标签str现在指向另一个对象。Q3:当你给一个新变量赋值时会发生什么?=到str?str2 = str str2.object_id # => 2002A:一个新的标签叫做str2创建,指向同一对象如str.Q4:如果被str和str2变了?str2.replace 'baz'str2 # => 'baz'str  # => 'baz'str.object_id # => 2002str2.object_id # => 2002答:两个标签仍然指向同一个对象,但该对象本身发生了变异(其内容已更改为其他内容)。这与原来的问题有何关系?这与Q3/Q4中的情况基本相同;该方法获得变量/标签的私有副本(str2)传递给它(str)。它不能更改标签的对象str 指点,但它可以更改.的内容它们都引用以包含Other的对象:str = 'foo'def mutate(str2)   puts "str2: #{str2.object_id}"   str2.replace 'bar'   str2 = 'baz'   puts "str2: #{str2.object_id}"endstr.object_id # => 2004mutate(str) # str2: 2004, str2: 2006str # => "bar"str.object_id # => 2004

白衣染霜花

Ruby是按引用传递还是按值传递?Ruby是按值传递的。一直都是。没有例外。如果没有。没有但是。下面是一个简单的程序,它演示了这一事实:def foo(bar)   bar = 'reference'endbaz = 'value'foo(baz)puts "Ruby is pass-by-#{baz}"# Ruby is pass-by-value
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Ruby