字符串受`downcase!`操作影响

时间:2016-02-17 10:08:46

标签: ruby string immutability

我试图逐行读取文件并处理数据。这是用户表数据。我正在提取account_iduser_id,然后在保存原始user_id的同时尝试向下转发user_id。我有以下代码:

# account_id | user_id | address | user_name |  passwordDigest
line = "g_1e035sadas-035e-45ba-9a1f-40d20000 |    MyUser999 | Alabama | Felix The Cat | 12Yoiqbdz/jCCDASD2kA8D4M5V9pZ3KyWiaj |  null |        null |" 

raw_line = line.split('|')
# => ["g_1e035sadas-035e-45ba-9a1f-40d20000 ", "    MyUser999 ", " Alabama ", " Felix The Cat ", " 12Yoiqbdz/jCCDASD2kA8D4M5V9pZ3KyWiaj ", "  null ", "        null "]

filtered_raw_line = raw_line.take(2)
# => ["g_1e035sadas-035e-45ba-9a1f-40d20000 ", "    MyUser999 "]

items = filtered_raw_line.collect{|x| x.strip || x }
# => ["g_1e035sadas-035e-45ba-9a1f-40d20000", "MyUser999"] 

original_user_id = items[-1]
# => "MyUser999"

items[-1].downcase!
# => "myuser999"

original_user_id
# => "myuser999"

我无法弄清楚为什么original_user_id在其中一个阵列单元格上执行downcase!操作后会发生变化。

3 个答案:

答案 0 :(得分:2)

  

我可能错过了一些OOP基本编程概念

有两个基本和不同的操作:

  1. 将对象分配给变量
  2. 向对象发送消息
  3. 它只能以这种方式工作,即只能为对象分配 1 ,只能将变量分配给 2 ,并且只能将消息发送给对象 3

    话虽如此,让我们来看看你的代码:

    items[-1]
    

    从数组中取出最后一个对象并返回它:字符串"MyUser999"

    original_user_id = items[-1]
    

    将该对象分配给变量original_user_id

    items[-1]original_user_id现在都指向同一个对象。

    items[-1].downcase!
    

    获取最后一个对象并向其发送downcase!消息。收到此消息后,该字符串将对其所有字符进行下载。

    此时,items[-1]original_user_id仍然引用相同的对象,即(现在已下放的)字符串"myuser999"

    original_user_id #=> "myuser999"
    

    正如预期的那样。

    1 虽然你可以写my_var = my_other_var,但这并没有将变量 my_other_var分配给my_var,但<分配给my_other_var的em> object 。

    2 Ruby确实有assignment methods,但它们只是用于发送消息的语法糖,即hash.default = 123等同于hash.default=(123)hash.send(:default=, 123)

    3 my_var.foo不会将消息foo发送到变量 my_var,而是发送到对象分配给my_var。同样地,array[0].foo不会将消息foo发送到数组“cell”,而是发送到索引0处的对象。

答案 1 :(得分:0)

你可以做

original_user_id = items2[-1].dup

object#dup创建对象的副本,而不是使用相同的引用

答案 2 :(得分:0)

您需要创建对象的副本或复制值,bcs downcase!修改原始字符串,您只需创建对象的引用,而不是重复的值。所以你可以轻松地做到这一点:

original_user_id = items[-1]

items[-1] = items[-1].downcase

original_user_id 
# => MyUser999

或者您可以修改代码

items = line.split('|').take(2).map{|s| s.strip}
original_user_id = items[-1]
#=> MyUser999
items[-1] = items[-1].downcase
#=> myuser999
original_user_id 
#=> MyUser999