@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变量中的错误。
虽然我正在尝试做的更多的是一个黑客(似乎没有工作)。我想知道为什么变量值被洗掉了。我理解通过引用传递,所以我想知道值如何可以保存在那个变量中而不被洗掉。
试试这个:——
1.object_id
#=> 3
2.object_id
#=> 5
a = 1
#=> 1
a.object_id
#=> 3
b = 2
#=> 2
b.object_id
#=> 5
标识符a包含值对象1的object_id 3,标识符b包含值对象2的object_id 5。
现在这样做:——
a.object_id = 5
#=> error
a = b
#value(object_id) at b copies itself as value(object_id) at a. value object 2 has object_id 5
#=> 2
a.object_id
#=> 5
现在,a和b都包含相同的object_id 5,它指向值对象2。
因此,Ruby变量包含object_ids来引用值对象。
执行以下操作也会给出错误:——
c
#=> error
但是这样做不会产生错误:——
5.object_id
#=> 11
c = 5
#=> value object 5 provides return type for variable c and saves 5.object_id i.e. 11 at c
#=> 5
c.object_id
#=> 11
a = c.object_id
#=> object_id of c as a value object changes value at a
#=> 11
11.object_id
#=> 23
a.object_id == 11.object_id
#=> true
a
#=> Value at a
#=> 11
这里标识符a返回值对象11,其对象id为23,即object_id 23位于标识符a,现在我们看到一个使用method的例子。
def foo(arg)
p arg
p arg.object_id
end
#=> nil
11.object_id
#=> 23
x = 11
#=> 11
x.object_id
#=> 23
foo(x)
#=> 11
#=> 23
foo中的Arg被赋值为x。
它清楚地表明参数是由值11传递的,值11本身是一个对象,对象id为23。
现在再看这个:——
def foo(arg)
p arg
p arg.object_id
arg = 12
p arg
p arg.object_id
end
#=> nil
11.object_id
#=> 23
x = 11
#=> 11
x.object_id
#=> 23
foo(x)
#=> 11
#=> 23
#=> 12
#=> 25
x
#=> 11
x.object_id
#=> 23
在这里,标识符arg首先包含object_id 23来引用11,在对值对象12进行内部赋值后,它包含object_id 25。但它不会改变在调用方法中使用的标识符x引用的值。
因此,Ruby是按值传递的,Ruby变量不包含值,但包含对值对象的引用。
Ruby是通过引用传递还是通过值传递?
Ruby是引用传递。总是这样。没有例外。没有如果。少啰嗦
下面是一个简单的程序,说明了这一事实:
def foo(bar)
bar.object_id
end
baz = 'value'
puts "#{baz.object_id} Ruby is pass-by-reference #{foo(baz)} because object_id's (memory addresses) are always the same ;)"
=> 2279146940 Ruby是引用传递的2279146940,因为object_id(内存地址)总是相同的;)
def bar(babar)
babar.replace("reference")
end
bar(baz)
puts "some people don't realize it's reference because local assignment can take precedence, but it's clearly pass-by-#{baz}"
=>有些人没有意识到它是引用,因为局部赋值可以优先,但它显然是引用传递
已经有了一些很好的答案,但我想在这里发布关于这个主题的一对权威的定义,但也希望有人能解释一下权威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中的所有东西都是对象,那么你可以说它是通过引用传递的。
我不同意这里的帖子声称它是通过价值,这对我来说似乎是迂腐的赛门铁克游戏。
然而,实际上它“隐藏”了行为,因为ruby提供的大多数操作都是“开箱即用”的——例如字符串操作,会生成对象的副本:
> astringobject = "lowercase"
> bstringobject = astringobject.upcase
> # bstringobject is a new object created by String.upcase
> puts astringobject
lowercase
> puts bstringobject
LOWERCASE
这意味着大多数时候,原始对象保持不变,给人一种ruby是“传递值”的感觉。
当然,在设计自己的类时,理解这种行为的细节对于功能性行为、内存效率和性能都很重要。