这是一个红宝石虫吗?
target_url_to_edit = target_url
if target_url_to_edit.include?("http://")
target_url_to_edit["http://"] = ""
end
logger.debug "target url is now #{target_url}"
这将返回不带http://
的target_url答案 0 :(得分:10)
您需要复制内存中对象,因为变量名只是对内存中对象的引用:
target_url_to_edit = target_url.dup
现在为target_url_to_edit
分配了原始对象的新副本。
对于您的情况,此代码可能只在一行中执行相同操作(无重复,否则为:)
target_url_to_edit = target_url.sub(%r{^http://}, "")
答案 1 :(得分:5)
不,这不是Ruby中的错误,这就是共享可变状态的工作方式,不仅仅是在Ruby中,而是在任何编程语言中。
这样想:我的妈妈称我为“儿子”,我的朋友称我为“Jörg”。如果我剪了头发,那么你用哪个名字来引用我并不重要:我是同一个人,无论你是叫“儿子”还是“Jörg”或“Mittag先生”还是“嘿, douchebag“,因此我的头发总是很短。如果你用不同的名字给我打电话,它就不会神奇地重新长出来。
在您的代码中也会发生同样的事情:您通过两个不同的名称来引用字符串,但使用哪个名称并不重要;如果字符串发生变化,则会发生变化。
当然,解决方案是不共享可变状态而不是改变共享状态,就像在@ hurikhan77的回答中一样。
答案 2 :(得分:0)
这不是一个错误。这是预期的行为,因为target_url_to_edit
指向内存中的同一对象target_url
,因为Ruby使用引用进行对象分配。如果你知道C,它就像指针一样。
答案 3 :(得分:-1)
以下是如何更改其行为以强制按值传递(请注意星号):
target_url_to_edit = *target_url.to_s
if target_url_to_edit.include?("http://")
target_url_to_edit["http://"] = ""
end
logger.debug "target url is now #{target_url}"
就像红宝石中的许多东西一样,很难找到它所记录的位置......