@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.inspect

if params[:user]
  @user.state = params[:user][:state]
  success = success & @user.save
end
logger.debug "--------------------LANG_ERRORS-------------102----------" 
                + lang_errors.full_messages.inspect

if lang_errors.full_messages.empty?

@user对象将错误添加到update_languages方法中的lang_errors变量中。 当我在@user对象上执行保存时,我丢失了最初存储在lang_errors变量中的错误。

虽然我正在尝试做的更多的是一个黑客(似乎没有工作)。我想知道为什么变量值被洗掉了。我理解通过引用传递,所以我想知道值如何可以保存在那个变量中而不被洗掉。


当前回答

参数是原始引用的副本。因此,您可以更改值,但不能更改原始引用。

其他回答

在传统术语中,Ruby是严格的值传递。但这不是你真正想要的。

Ruby doesn't have any concept of a pure, non-reference value, so you certainly can't pass one to a method. Variables are always references to objects. In order to get an object that won't change out from under you, you need to dup or clone the object you're passed, thus giving an object that nobody else has a reference to. (Even this isn't bulletproof, though — both of the standard cloning methods do a shallow copy, so the instance variables of the clone still point to the same objects that the originals did. If the objects referenced by the ivars mutate, that will still show up in the copy, since it's referencing the same objects.)

参数是原始引用的副本。因此,您可以更改值,但不能更改原始引用。

Ruby是严格意义上的值传递,但是值是引用。

这可以称为“pass-reference-by-value”。这篇文章有我读过的最好的解释:http://robertheaton.com/2014/07/22/is-ruby-pass-by-reference-or-pass-by-value/

按值传递引用可以简单地解释如下:

函数接收(并将访问)调用者在内存中使用的同一对象的引用。但是,它不接收调用方存储该对象的盒子;与pass-value-by-value一样,函数提供自己的方框,并为自己创建一个新变量。

结果行为实际上是引用传递和值传递的经典定义的组合。

已经有了一些很好的答案,但我想在这里发布关于这个主题的一对权威的定义,但也希望有人能解释一下权威Matz (Ruby的创造者)和David Flanagan在他们的O'Reilly著作《Ruby编程语言》中所说的意思。

[from 3.8.1: Object References] When you pass an object to a method in Ruby, it is an object reference that is passed to the method. It is not the object itself, and it is not a reference to the reference to the object. Another way to say this is that method arguments are passed by value rather than by reference, but that the values passed are object references. Because object references are passed to methods, methods can use those references to modify the underlying object. These modifications are then visible when the method returns.

直到最后一段,尤其是最后一句,我才明白这一切。往好了说是误导,往坏了说是混淆。对值传递引用的修改如何以任何方式改变底层对象?

Ruby是通过引用传递还是通过值传递?

Ruby是值传递。总是这样。没有例外。没有如果。少啰嗦

下面是一个简单的程序,说明了这一事实:

def foo(bar)
  bar = 'reference'
end

baz = 'value'

foo(baz)

puts "Ruby is pass-by-#{baz}"
# Ruby is pass-by-value