Ruby惯用法

导读:
  Ruby有不少惯用法,这里略作一些介绍,也方便阅读他人代码:
   迭代
  一般写法:
  [code] for i in (1..10) puts i end[/code]
  习惯写法:
  [code](1..10).each{|i| puts i}或1.upto(10){|i| puts i} # from njmzhang[/code]
   ||=赋值
  一般写法:
  [code] number = 1 if number.nil? number = 1 unless number[/code]
  习惯写法:
  [code] number ||= 1[/code]
   程序入口
  [code] if __FILE__ == $0或 if $PROGRAM_NAME == __FILE__[/code]
  这个相当于main(), 逻辑判断的意思当程序名($0或另一个)和当前文件名(__FILE__)一致时,也就是当前文件是被单独执行的而不是被别的文件调用。这个方法还有个用法是作为unit test使用。
   预设变量和特殊记号
  类似$0的Perl风格预设常量还有很多,参见Programming Ruby p319
  其中比较常用的如$:代表库搜索路径,修改方法常见有:
  [code]$:.unshift('buildscript') # from gigix或$: <   后一种方法使用了相对路径,因为Ruby的module不要求namespace和文件目录结构要对应一致,很多时候统统放一个目录里
  %w格式化命令(from qiezi) 可以少打几个引号
  [code]%w{a b c d} #等价 ['a', 'b', 'c', 'd'] [/code]
  ``(~键下的撇号)用来执行shell外部命令,如:
  [code]`help`[/code]
   inject
  一般写法:
  [code] result = [](1..10).each{|item| result <
  习惯写法:
  [code](1..10).inject([]){|array, item| array <
  inject有点难理解,相当于python的reduce和一些FP里的fold。inject的块变量有两个(这里是array和item),第二个变量(item)用来枚举被inject的集合(这里是(1..10)这个range), 而第一个变量(array)由inject的参数初始化(这里是[],可选),并在block被反复执行时保持持久(相当于静态变量),而item则在每次枚举时被更新为下一个值。我们再看一下inject的另一种通常用法就会更明白了:求和
  [code](1..10).inject{|sum, item| sum += item}这个等于(1..10).inject(0){|sum, item| sum += item}[/code]
  也就是块变量sum被初始化成0然后反复迭代执行块的内容,最后返回sum
   并行赋值
  这个很多人都知道了,比如:
  [code] a,b = 0, 1 a,b = b, a # 交换a,b[/code]
  当然可以延伸出一些很诡异的变化,不提倡使用阿
  还有一个用法是让函数返回“多个结果”(不是多个对象),如:
  [code] def test 1,2 end x, y = test #x = 1, y = 2 [/code]
  这个njmzhang说的很对,其实函数返回的是一个array,然后再并行匹配到变量上去。(所以我对多个结果特别加了引号)
  这显然是个syntax sugar,你随便用逗号分割几个变量是不会自动组成array的。
  注意这种并行匹配当两遍不平衡时会造成的问题:
  [code] a,b = [1,2,3] # a = 1, b = 2, 3被丢弃 a,b,c = [1,2] # a = 1, b = 2, c = nil 被初始化成nil [/code]
   *的匹配
  一般来说*用于把一个array展开:
  [code] a, *b = [1,2,3] #a = 1, b = [2,3][/code]
  类似FP里的x:xs(haskell), x::xs(ocaml), [a | b] (erlang from 布娃娃)
   rescue简单用法
  [code] begin 1/0 rescue puts 'wrong' end[/code]
  可以简化为
  [code]1/0 rescue puts 'wrong'[/code]
   命名参数的默认值
  ruby有默认参数,但其实没有所谓keyword argument,而是提供一个syntax sugar用hash模拟。但是怎么像Rails的方法那样同时利用命名参数和默认参数值呢?
  [code] def image(opt={}) default_opt = {:height => 25, :width => 10} default_opt.merge! opt #opt中同样key的内容会覆盖default_opt中key的value end[/code]
   精细duck typing控制
  duck typing的精神就是行为决定类型,而不是相反
  [code] a = []#不用 if a.kind_of? Array then a <<1 if a.instance_of? Array then a <<1#而用 if a.respond_to? :<< then a <<1[/code]
   获取metaclass
  这也比较常见了,各种动态伎俩的开始
  [code] sing = class <
   符号转换到Proc
  一般写法:
  [code](1..10).map{|item| item.succ}[/code]
  习惯写法:
  [code](1..10).map(&:succ)[/code]
  map(fun(x))般的FP风格
  注意这是Rails特有的,通过ActiveSupport对Symbol插入to_proc方法。
  不用Rails怎么办呢?一种办法是借助Ruby Facets库(gem install facets):
  [code]require 'facet/symbol/to_proc‘[/code]
  Facets库包括大量对Ruby核心类的扩展,是个有趣而又危险的大杂烩,也许我以后会另外再专门介绍一下。
  [code]

本文转自
http://www.javaeye.com/topic/24642
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值