2013-09-27 195 views
0

红宝石2.1将有一个冻结的绳子,让对象不是重新创建每次解释整个运行时间,即红宝石2.1冻结串

my_hash["abcd"f] = 123 

为什么不能解释自动检测此字符串不会改变,只是自动冻结它?

或者,pre-ruby 2.1一旦解释器开始运行,任何代码如何更改这样的字符串?如果我们说“abcd”需要被冻结,那么就必须有某种方式来改变它。

- 更新:上面的问题进行了更新,所以在下面的评论是有点尴尬,但并非是针对以前的代码示例的情况不是很好。

- UPDATE:http://globaldev.co.uk/2014/05/ruby-2-1-in-detail/ Ruby键会自动冻结。

+0

考虑'mydef.downcase!',它会修改返回的字符串。现在,如果你想在2.1之前的冻结/ interned字符串,你只需使用符号。 –

回答

1

Ruby是一种动态语言。没有静态编译,解释器很难预先知道谁最终会访问和修改变量。

我们来看下面的例子。你有一个string

str = "foo" 

,然后后面的代码中你有

str.upcase! 
# => "FOO" 

这个例子是非常微不足道的,即使是简单的解析器,了解该字符串突变。但是,让我们添加一些更复杂

str = "foo" 
method = ["up", "case"] 
str.send((method << "!").join) 
# => "FOO" 

这正是生产之前相同的结果,但该方法不是静态脚本编码。相反,它是在运行时在字符串上动态执行的计算的结果。

但是等等,让我们把它变得更加复杂。

str = "foo" 
method = [ARGV.first, "case"] 
str.send((method << "!").join) if ARGC.to_i > 0 
# => "FOO" 

在这种情况下,假设我从命令行传递参数,转换方法将被计算并应用于字符串。

正如你所猜测的,在这两种情况下知道str将要改变的唯一方法是通过实际执行代码。

这些例子也应该回答你的问题

How could any code change such a string once the interpreter has started running? If we say that "abcd" needs to be frozen, then there must be some way of changing it.

补充说明的第二部分,我想指出的是,“冻结字符串文字”功能,最近已演变,它现在足够将变量标记为frozen

In Ruby 2.1, "str".freeze is optimized by the compiler to return a single shared frozen strings on every invocation. An alternative "str"f syntax was implemented initially, but later reverted.

2
  • 关于你提到的第一个问题:

    因为解释不能预见是否该字符串实例会被任何破坏性的方法,在以后修改。

  • 关于你提到的第二个问题( “或” 后):

    通过任何对String破坏性的方法,如reverse!prependconcat

+0

如果字符串被自动冻结,'mydef.sub!('a','o')'会抛出不需要的RuntimeError。这是你的观点的一个例子吗? (这取代了之前措辞不佳的评论。) –

+0

我试过mydef.sub!('a','!')。下一次通话时,mydef仍会返回'abcd'。 – Daniel

+0

我清理了措辞@CarySwoveland – Daniel