Ruby有不少惯用法,这里略作一些介绍,也方便阅读他人代码:
迭代
一般写法:
for i in (1..10)
puts i
end
习惯写法:
- (1..10).each{|i| puts i}
- 或
- 1.upto(10){|i| puts i} # from njmzhang
(1..10).each{|i| puts i} 或 1.upto(10){|i| puts i} # from njmzhang
||=赋值
一般写法:
- number = 1if number.nil?
- number = 1 unless number
number = 1 if number.nil? number = 1 unless number
习惯写法:
- number ||= 1
number ||= 1
程序入口
- if __FILE__ == $0
- 或
- if $PROGRAM_NAME == __FILE__
if __FILE__ == $0 或 if $PROGRAM_NAME == __FILE__
这个相当于main(), 逻辑判断的意思当程序名($0或另一个)和当前文件名(__FILE__)一致时,也就是当前文件是被单独执行的而不是被别的文件调用。这个方法还有个用法是作为unit test使用。
预设变量和特殊记号
类似$0的Perl风格预设常量还有很多,参见Programming Ruby p319
其中比较常用的如$:代表库搜索路径,修改方法常见有:
- $:.unshift('buildscript') # from gigix
- 或
- $: << File.join(File.dirname(__FILE__), 'CurrentClass')
$:.unshift('buildscript') # from gigix 或 $: << File.join(File.dirname(__FILE__), 'CurrentClass')
后一种方法使用了相对路径,因为Ruby的module不要求namespace和文件目录结构要对应一致,很多时候统统放一个目录里
%w格式化命令(from qiezi) 可以少打几个引号
- %w{a b c d} #等价 ['a', 'b', 'c', 'd']
%w{a b c d} #等价 ['a', 'b', 'c', 'd']
``(~键下的撇号)用来执行shell外部命令,如:
- `help`
`help`
inject
一般写法:
- result = []
- (1..10).each{|item| result << item}
result = [] (1..10).each{|item| result << item}
习惯写法:
- (1..10).inject([]){|array, item| array << item}
(1..10).inject([]){|array, item| array << item}
inject有点难理解,相当于python的reduce和一些FP里的fold。inject的块变量有两个(这里是array和item),第二个变量(item)用来枚举被inject的集合(这里是(1..10)这个range), 而第一个变量(array)由inject的参数初始化(这里是[],可选),并在block被反复执行时保持持久(相当于静态变量),而item则在每次枚举时被更新为下一个值。我们再看一下inject的另一种通常用法就会更明白了:求和
- (1..10).inject{|sum, item| sum += item}
- 这个等于
- (1..10).inject(0){|sum, item| sum += item}
(1..10).inject{|sum, item| sum += item} 这个等于 (1..10).inject(0){|sum, item| sum += item}
也就是块变量sum被初始化成0然后反复迭代执行块的内容,最后返回sum
并行赋值
这个很多人都知道了,比如:
- a,b = 0, 1
- a,b = b, a # 交换a,b
a,b = 0, 1 a,b = b, a # 交换a,b
当然可以延伸出一些很诡异的变化,不提倡使用阿
还有一个用法是让函数返回“多个结果”(不是多个对象),如:
- def test
- 1,2
- end
- x, y = test #x = 1, y = 2
def test 1,2 end x, y = test #x = 1, y = 2
这个njmzhang说的很对,其实函数返回的是一个array,然后再并行匹配到变量上去。(所以我对多个结果特别加了引号)
这显然是个syntax sugar,你随便用逗号分割几个变量是不会自动组成array的。
注意这种并行匹配当两遍不平衡时会造成的问题:
- a,b = [1,2,3] # a = 1, b = 2, 3被丢弃
- a,b,c = [1,2] # a = 1, b = 2, c = nil 被初始化成nil
a,b = [1,2,3] # a = 1, b = 2, 3被丢弃 a,b,c = [1,2] # a = 1, b = 2, c = nil 被初始化成nil
*的匹配
一般来说*用于把一个array展开:
- a, *b = [1,2,3] #a = 1, b = [2,3]
a, *b = [1,2,3] #a = 1, b = [2,3]
类似FP里的x:xs(haskell), x::xs(ocaml), [a | b] (erlang from 布娃娃)
rescue简单用法
- begin
- 1/0
- rescue
- puts 'wrong'
- end
begin 1/0 rescue puts 'wrong' end
可以简化为
- 1/0 rescue puts 'wrong'
1/0 rescue puts 'wrong'
命名参数的默认值
ruby有默认参数,但其实没有所谓keyword argument,而是提供一个syntax sugar用hash模拟。但是怎么像Rails的方法那样同时利用命名参数和默认参数值呢?
- def image(opt={})
- default_opt = {:height => 25, :width => 10}
- default_opt.merge! opt #opt中同样key的内容会覆盖default_opt中key的value
- end
def image(opt={}) default_opt = {:height => 25, :width => 10} default_opt.merge! opt #opt中同样key的内容会覆盖default_opt中key的value end
精细duck typing控制
duck typing的精神就是行为决定类型,而不是相反
- a = []
- #不用
- if a.kind_of? Array then a << 1
- if a.instance_of? Array then a << 1
- #而用
- if a.respond_to? :<< then a << 1
a = [] #不用 if a.kind_of? Array then a << 1 if a.instance_of? Array then a << 1 #而用 if a.respond_to? :<< then a << 1
获取metaclass
这也比较常见了,各种动态伎俩的开始
- sing = class << self; self; end
sing = class << self; self; end
符号转换到Proc
一般写法:
- (1..10).map{|item| item.succ}
(1..10).map{|item| item.succ}
习惯写法:
- (1..10).map(&:succ)
(1..10).map(&:succ)
map(fun(x))般的FP风格
注意这是Rails特有的,通过ActiveSupport对Symbol插入to_proc方法。
不用Rails怎么办呢?一种办法是借助Ruby Facets库(gem install facets):
- require 'facet/symbol/to_proc‘
require 'facet/symbol/to_proc‘
Facets库包括大量对Ruby核心类的扩展,是个有趣而又危险的大杂烩,也许我以后会另外再专门介绍一下。
相关推荐
此外,Ruby作为动态语言,类型检查是在运行时进行的,这可能会让习惯于静态类型语言的开发者感到不适应。然而,这也意味着更高的灵活性,可以更快地进行迭代和实验。 《程序员实务:从熟练工到大师》一书建议程序员...
Ruby/tk是一种基于Ruby语言的图形用户界面(GUI)库,它基于Tcl/Tk工具包并进行了封装以适应Ruby的语法和习惯。 #### 1. 引入Ruby/tk 在使用Ruby/tk之前,首先需要确保已经正确安装了Ruby环境,并且安装了Ruby/tk库...
总的来说,"ruby测试代码1"涉及的是使用Ruby进行测试实践,可能涵盖了MiniTest或RSpec的基本用法。同时,文件名提示了可能需要处理游戏相关的数据,这可能需要对文件I/O和特定文件格式有深入理解。在实际的开发过程...
Ruby 2.7.1对语法也进行了一些改进,例如弃用了`Hash#default`方法的旧用法,鼓励使用`Hash#default_proc`,后者提供了更灵活的默认值处理方式。此外,`Array#bsearch`方法现在支持`&`运算符,使得在数组中查找指定...
《笨方法学Ruby》是针对初学者的一本中文教程,旨在...通过学习《笨方法学Ruby》,读者不仅能够掌握Ruby语言的基本用法,还能建立起良好的编程习惯,为深入学习Ruby on Rails框架或其他基于Ruby的技术打下坚实的基础。
此外,本书还会涵盖Ruby的错误处理和异常处理机制,以及测试驱动开发(TDD)和集成测试的相关知识,帮助读者建立良好的编程习惯和测试意识。 文件名列表中的“[Ruby完全自学手册].邓蔚.扫描版.pdf”显然是这本书的...
7. **灵活的配置**:Pry允许用户自定义各种设置,例如绑定到特定的对象、改变提示符样式、甚至添加自定义命令,以满足个人开发习惯。 开源项目的特性意味着Pry是免费且透明的,由全球社区共同维护和改进。开发者...
- **保持代码整洁**:遵循良好的编程习惯,如使用有意义的变量名、注释等。 - **测试数据分离**:将测试数据从测试代码中分离出来,便于管理和维护。 - **异常处理**:合理地处理异常情况,如超时、元素不存在等,...
他向我们展示了许多可以加快 Ruby 代码运行速度的习惯用法。 他启发我将这些记录下来,让更多人知道。 我尝试链接到真正的提交,以便人们可以看到这在现实世界中确实有好处。 这并不意味着您总是可以盲目地将一个...
书中可能还会涉及TDD(Test-Driven Development,测试驱动开发)和BDD(Behavior-Driven Development,行为驱动开发)在Rails中的实践,介绍RSpec和Cucumber等测试工具,强调编写可测试的代码和良好的测试习惯对项目...
在描述中提到的“Manpages:为ruby gems添加手册页支持”,意味着这个更新或项目的主要目标是改善 RubyGems 的用户体验,通过创建和集成手册页,使得开发者可以更轻松地查找和理解 gem 中的函数、方法和命令的用法。...
然而,对于那些习惯于使用Jupyter Notebook进行数据分析、可视化或者教学的用户来说,将Notebook集成到Jekyll站点中可能是个挑战。这就是`Jekyll Jupyter Notebook`插件的作用所在。这个插件为Jekyll添加了对Jupyter...
注意:正在重新思考... 自该项目于2011年开始以来,Scala进行了相当多的... 将支持all_catch习惯用法,以转换可能将异常抛出到Option或Either结果中的块。 如果证明这样做有用(并且非常适合Ruby),那么也可以实现更
我们想法的灵感是尝试在诸如 Ruby 或 Smalltalk 之类的语言上试验错误热点,在这些语言中您通常不会使用某些编程结构,例如 C 或 Java 中的if 、 for或while ,而是依赖特定的习惯用法或协议,或者尝试利用多态性来...
而在命令行工具中,它可以确保输出的信息符合用户的习惯,如正确地格式化数字和货币。 为了更好地利用 Ruby Locale,开发者需要了解如何导入和初始化这个库,如何设置和切换 locale,以及如何访问和使用提供的数据...
2. **RSpec**: 学习RSpec的基本用法,如`describe`、`it`、`before`、`expect`等关键字,以及如何编写模拟对象(mocks和stubs)和期望。 3. **Test-Driven Development (TDD)**: 理解TDD的原则,包括先写失败的测试...
14. **Web开发**:Ruby on Rails框架的基础和高级用法,包括路由、控制器、视图、模型等。 每个知识点都通过实例展示,让你能够快速上手并在实践中应用。无论你是初学者还是有经验的开发者,《Ruby Cookbook》都能...
6. **日期和时间格式化**:根据选定的地区,`Ri18n`库可以自动格式化日期和时间,以符合当地的习惯。 7. **数字和货币格式**:类似地,它也处理数字和货币的本地化显示,如小数点、千位分隔符等。 8. **代码整合**...