`
ihuashao
  • 浏览: 4549604 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

Ruby 字符串 Frozen 和 unfreeze 的问题

阅读更多
Ruby 字符串 Forzen 和 unfreeze 的问题
字符串处理是学习一门新语言面临的第一个问题 题记

看超人归来的时候,记得里面有个超人叫freeze ? 这家伙有一招,喝口水,然后往外一喷 一切就 freeze 。这不 ruby 也有freeze 。

今天我写的代码中有这样一行:
strTmp = sd[0].to_s.gsub!(/..../ , '' ) ,sd是一个hash

执行的时候出错了:`gsub!': can't modify frozen string (TypeError)
既然forzen了,我想当然的把代码改成:

sdStr = sd[0].to_s
strTmp = sdStr.to_s.gsub!(/..../ , '' )
错误照旧: `gsub!': can't modify frozen string (TypeError)

想起今天孟岩写的:Ruby之symbol研究 ,的确字符串的处理上ruby有很多特色。


3. 为什么可以节省内存?Ruby中的String是可变对象,这一点跟Java、C#、Python都不一样。注意跟某些C++标准库中的COW的 basic_string<T>也不一样。Ruby中每一个String都可以就地改变。可能是因为这个原因,Ruby中两个内容相同的字符 串文本量实际上是两个不同的对象。

a = "hello"
b = "hello"

虽然俩字符串内容都一样,但是你比一下a和b,就知道a.object_id != b.object_id,它们指向的不是同一个对象。结果反而很像未经string pooling优化的C语言的行为。到底immutable好还是mutable好,或者还是貌似聪明的COW好,见仁见智了。不过Ruby的设计在把字 符串用作hash key的时候毛病就大了。比如你写:

h["ruby"].name = "Ruby"
h["ruby"].author = "matz"
h["ruby"].birth_year = 1995

的时候,"ruby"这个字符串动态生成了三次,占用三倍内存。这就严重地浪费了内存。而用:ruby做为key,因为在整个运行过程中,Ruby runtime保证名为:ruby的symbol对象只有一个,所以就不用生成三个,节省内存。



在看参考手册的时候才发现 ruby 的 string 有 freeze 方法 ,却没有提供 unfreeze 。最后只好老老实实看参考手册用:

sdUrl = sd[0].to_s.dup 的方法解决了 frozen 的问题。

不过 matz 说或许未来会提供吧

Uh, maybe. Some part of string copy-on-write system depends on the
fact that frozen strings would never be modified. I'm not sure proper
copying on those two functions make unfreeze possible. When I confirm
it, I would happily add Object#unfreeze to the future Ruby.
matz.


Ruby中不只是字符串会碰到freeze的问题,Array 和 Hash 的 frozen 使用更需要注意了,可以参考下面的文章:

Ruby Array and Hash frozen behavior

接触ruby一段时间了,ruby给了我很快乐的感觉,ruby比python更自然。


以前分析 java nanning (南宁) aop 模块的一些经验 再加上现在用ruby的感觉,发现 ruby 作为领域语言确实有很多优势,这不
A taste of evil.rb: using DL to unfreeze objects 又给了我更多的启发。

相关链接

Ruby 字符串 Forzen 和 unfreeze 的问题
Ruby 字符串 Forzen 和 unfreeze 的问题
分享到:
评论

相关推荐

    icicle:微小的互斥体

    :snowflake: 冰柱 ... isFrozen ( a , 'waitABit' ) ; // true icicle . unfreeze ( a , 'waitABit' ) ; // true - lock is unset icicle . unfreeze ( a , 'waitABit' ) ; // false - lock isn’t set icicle . is

    Android代码-ASNE

    Unfreeze project - merge all puls for master branch - current version was not tested - NOT STABLE Sorry, but I freeze work on project for some time(I hope not long, nearly month) - too busy. I saw all...

    FreezeKill:用户 PhillyCheezsteak 在 Bukkit 请求插件论坛上请求的新 bukkit 插件

    = 使用玩家名称和时间限制(以秒为单位)将玩家冻结指定的秒数。 他们将被要求在时间用完之前杀死敌对暴徒,否则他们会死/unfreeze [playerName] = 使用被冻结玩家的玩家名将他们从之前的状态中

    小额支付API专用SDK(.net版)下载

    alipay.micropay.order.direct.pay 单笔直接支付 alipay.micropay.order.freezepayurl.get 查询冻结金支付地址 ...alipay.micropay.order.unfreeze解冻冻结订单 alipay.micropay.order.freeze 创建冻结订单

    MobaXterm Pro 11.0.3816

    Improvement: after terminal has been paused (Ctrl+S), any key will “unfreeze” it. Many users thought that terminal was frozen after accidentally hitting Ctrl+S Bugfix: after setting the graphical ...

Global site tag (gtag.js) - Google Analytics