不可变与可变

时间:2015-07-22 21:54:06

标签: ruby

我不明白行中发生了什么 print buggy_logger << "\n" # <- This insertion is the bug. 调用上面的行时,为什么变量状态会发生变化? 我关注此网站http://www.reactive.io/tips/2009/01/11/the-difference-between-ruby-symbols-and-strings/

status = "peace"

 buggy_logger = status

 print "Status: "
 print buggy_logger << "\n" # <- This insertion is the bug.

def launch_nukes?(status)
  unless status == 'peace'
   return true
  else
return false
 end
end

print "Nukes Launched: #{launch_nukes?(status)}\n"

输出是:

=&GT;现状:和平

=&GT; Nukes发起:真实

2 个答案:

答案 0 :(得分:2)

您的问题是&#34;为什么变量会发生变化?&#34;

答案是因为buggy_logger拥有对status的引用。通过检查object_id

轻松证明
irb(main):001:0> a = "hi"
=> "hi"
irb(main):002:0> a.object_id
=> 24088560
irb(main):003:0> b = a
=> "hi"
irb(main):004:0> b.object_id
=> 24088560
irb(main):005:0>

要创建副本,请使用+或任何非变异操作符。请勿使用<<

irb(main):010:0> c = a + " guys"
=> "hi guys"
irb(main):011:0> c.object_id
=> 26523040
irb(main):012:0>

答案 1 :(得分:1)

由于status = "peace"是一个字符串,因此在buggy_logger << "\n"运行时,它会将buggy_logger(以及随后的status)的字符串更新为&# 34;和平\ n&#34;

因此,当运行该方法时,它将返回true,因为status != "peace"了。

现在,如果在开始时使用了符号status = :peace,则无法使用&#34; \ n&#34;附属物。因此,该方法将返回false,因为status == :peace

符号版本:

status = :peace

 buggy_logger = status

 print "Status: "
 #print buggy_logger << "\n" # This is no longer possible. It will cause an error

def launch_nukes?(status)
  unless status == :peace
   return true
  else
return false
 end
end

print "Nukes Launched: #{launch_nukes?(status)}\n"  # <- Returns FALSE