Ruby 开发遇到的坑

简介: Ruby 开发遇到的坑

最近在看Liquid源码时看到一句

def render(*args)
      return ''.freeze if @root.nil?
      ...
end

所以我就看了看freeze方法的定义。 它是 Object 的实例方法,所以基本上所有的 Ruby 对象都继承了 Object 的 freeze 方法。 为了进一步搞明白作者写 ‘’.freeze的意图,我就在命令行试了试 freeze

# ruby 2.2.3
 > a = ''
 => "" 
> a.freeze
 => "" 
 > a << 'b'
RuntimeError: can't modify frozen String
    from (irb):3
    from /home/i/.rvm/rubies/ruby-2.2.3/bin/irb:11:in `<main>'
> a += 'c'
 => "c" 
 > a
 => "c" 
 > a.freeze
 => "c" 
 > a << 'b'
RuntimeError: can't modify frozen String
    from (irb):7
    from /home/i/.rvm/rubies/ruby-2.2.3/bin/irb:11:in `<main>'
 > a += 'd'
 => "cd"

freeze只是禁止了<<操作,但是对于 =、+却可以,而且一旦使用了运算符,或者说调用了+、=方法,变量又从frozen状态回到了正常状态,

> a.freeze
 => "cd" 
 > a << 'e'
RuntimeError: can't modify frozen String
    from (irb):12
    from /home/i/.rvm/rubies/ruby-2.2.3/bin/irb:11:in `<main>'
 > a.frozen?
 => true 
> a += 'e'
 => "cde" 
 > a.frozen?
 => false

官方文档是这样说的

There is no way to unfreeze a frozen object. See also Object#frozen?.

但是我们做到了

对于 Fixnum, Bignum, Float, Symbol 来说永远是 Frozen 状态。

Objects of the following classes are always frozen: Fixnum, Bignum, Float, Symbol.

我又试了下数组

> a = [1]
 => [1] 
 > a.freeze
 => [1] 
 > a << 2
RuntimeError: can't modify frozen Array
    from (irb):44
    from /home/i/.rvm/rubies/ruby-2.2.3/bin/irb:11:in `<main>'
 > a += [2]
 => [1, 2] 
 > a
 => [1, 2] 
 > a.frozen?
 => false 
 > a.freeze
 => [1, 2] 
 > a -= [2]
 => [1] 
 > a.frozen?
 => false

所以,对于数组来说,也并没有真正的做到 freeze。 对于frozen的对象来说,只是禁止了<<操作符而已。不知道是 bug 还是故意设计的。

虽然,这个方法用的相对比较少,但是记录在这里,希望起到抛砖引玉的作用。

今天起来一看,果然+操作符返回的是一个新的字符串,而<<concat的别名,返回对象本身。 所以freeze是对对象本身的操作。

a.freeze 冻结了 a 指向的对象,<< 直接修改对象,操作被阻止。+=a 指向新的对象,操作没有被阻止。


相关文章
|
4月前
|
开发框架 安全 前端开发
使用Ruby on Rails进行快速Web开发
【5月更文挑战第27天】Ruby on Rails是一款基于Ruby的高效Web开发框架,以其快速开发、简洁优雅和强大的社区支持著称。遵循“约定优于配置”,Rails简化了开发流程,通过MVC架构保持代码清晰。安装Ruby和Rails后,可使用命令行工具创建项目、定义模型、控制器和视图,配置路由,并运行测试。借助Gem扩展功能,优化性能和确保安全性,Rails是快速构建高质量Web应用的理想选择。
|
4月前
|
敏捷开发 持续交付 开发工具
Ruby:软件外包开发的强大利器
在 Ruby 软件外包开发中,常用工具和技术包括 Ruby on Rails 框架、Gem 包管理器、RSpec 测试框架、Capistrano 部署工具、Docker 容器化平台、持续集成工具(如 Jenkins)、Git 版本控制与代码托管平台、IDE(如 Visual Studio Code)以及 Agile 方法和工具(如 Trello)。这些工具能提升效率、保证质量、简化流程,促进项目成功和客户满意度。
269 2
|
4月前
|
监控 安全 测试技术
深入了解Ruby项目的维护与定制开发
本文介绍了Ruby项目的维护与定制开发,包括维护任务、定制开发流程和技巧等内容,旨在帮助开发者更好地理解和应用Ruby语言
238 1
|
12月前
|
数据库 开发者 Ruby
使用 Ruby 进行快速原型开发和敏捷编程
在当今的软件开发领域,敏捷方法已经成为广泛采用的开发方式。而作为一门灵活且功能强大的动态编程语言,Ruby 提供了许多工具和技巧,使它成为进行快速原型开发和敏捷编程的理想选择。
78 0
|
机器人 图形学 Ruby
【Unity开发实战】—— 2D项目1 - Ruby‘s Adventure 游戏中动画制作(4-1)
【Unity开发实战】—— 2D项目1 - Ruby‘s Adventure 游戏中动画制作(4-1)
227 0
【Unity开发实战】—— 2D项目1 - Ruby‘s Adventure 游戏中动画制作(4-1)
|
定位技术 API 图形学
【Unity开发实战】—— 2D项目1 - Ruby‘s Adventure 游戏世界中各个对象的交互(3-1)
【Unity开发实战】—— 2D项目1 - Ruby‘s Adventure 游戏世界中各个对象的交互(3-1)
269 0
【Unity开发实战】—— 2D项目1 - Ruby‘s Adventure 游戏世界中各个对象的交互(3-1)
|
存储 定位技术 图形学
【猿创征文|Unity开发实战】—— 2D项目1 - Ruby‘s Adventure 游戏地图绘制(2-1)
【猿创征文|Unity开发实战】—— 2D项目1 - Ruby‘s Adventure 游戏地图绘制(2-1)
266 0
【猿创征文|Unity开发实战】—— 2D项目1 - Ruby‘s Adventure 游戏地图绘制(2-1)
|
XML 程序员 API
Ruby 开发社区重量级程序员 Jim Weirich 2月19日去世
Ruby 开发社区重量级程序员 Jim Weirich 于2月19日去世,死因可能是心脏麻痹。他原名 James Nolan,是Ruby 社区的重要贡献者,开发了非常流行的 Rake —— 几乎被所有Ruby 开发者使用的开发工具。他在Ruby 社区非常活跃,在世界各地经常演讲,为Ruby 的推广做的极大的贡献。这是3天前他在GitHub上的最后一条 commit。
186 0
Ruby 开发社区重量级程序员 Jim Weirich 2月19日去世
|
IDE 测试技术 开发工具