`
cookoo
  • 浏览: 647132 次
  • 性别: Icon_minigender_1
  • 来自: Shanghai
社区版块
存档分类
最新评论

Ruby惯用法

    博客分类:
  • Ruby
阅读更多
Ruby有不少惯用法,这里略作一些介绍,也方便阅读他人代码:

迭代
一般写法:

for i in (1..10)
puts i
end

习惯写法:
(1..10).each{|i| puts i}
或
1.upto(10){|i| puts i} # from njmzhang



||=赋值
一般写法:
number = 1 if number.nil?
number = 1 unless number

习惯写法:
number ||= 1



程序入口
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') 

后一种方法使用了相对路径,因为Ruby的module不要求namespace和文件目录结构要对应一致,很多时候统统放一个目录里

%w格式化命令(from qiezi) 可以少打几个引号
%w{a b c d} #等价 ['a', 'b', 'c', 'd'] 


``(~键下的撇号)用来执行shell外部命令,如:
`help`



inject
一般写法:
result = []
(1..10).each{|item| result << 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}

也就是块变量sum被初始化成0然后反复迭代执行块的内容,最后返回sum


并行赋值
这个很多人都知道了,比如:
a,b = 0, 1
a,b = b, a # 交换a,b

当然可以延伸出一些很诡异的变化,不提倡使用阿

还有一个用法是让函数返回“多个结果”(不是多个对象),如:
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 



*的匹配
一般来说*用于把一个array展开:
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

可以简化为
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



精细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



获取metaclass
这也比较常见了,各种动态伎俩的开始
sing = class << self; self; end



符号转换到Proc
一般写法:
(1..10).map{|item| item.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‘


Facets库包括大量对Ruby核心类的扩展,是个有趣而又危险的大杂烩,也许我以后会另外再专门介绍一下。


  


  
分享到:
评论
4 楼 njmzhang 2006-09-19  
loop的写法有多种,
1.upto(10) {...}
10.downto(1) {...}
1.step(10, 2) {...}
3 楼 gigix 2006-09-19  
buaawhl 写道
第一份收藏品。学习中。受益匪浅。great thanks。
另外,源文件/目录/namespace 管理、引入等有什么best practice?
我知道一个require,load 啥的。
还看到有些人实现了ruby import module。

另外,一点疑惑。
引用

(1..10).inject([]){|array, item| array << item}
inject有点难理解,相当于python的reduce和一些FP里的fold。inject的块变量有两个(这里是array和 item),第二个变量(item)用来枚举被inject的集合(这里是(1..10)这个range), 而第一个变量(array)由inject的参数初始化(这里是[],可选),并在block被反复执行时保持持久(相当于静态变量),而item则在每次枚举时被更新为下一个值。是不是越看越晕呼呢?哈哈哈


这个地方虽然没有太看懂,但是感觉和List Comprehension有些像。因为这里产生的结果是一个Array ( like List)。
而Reduce, Fold的结果一般是积累成一个总值。比如,sum。
当然,这只是我的印象。我对ruby inject, Reduce/Fold, List Comprehension了解都不深。
提出疑惑,盼高手解惑。

再看一眼,仿佛这Ruby Inject很符合Reduce/Fold的形式,都是把当前结果和下一个元素作为两个参数继续向下执行。

respond to 确实是个 best practice。

引用

命名参数的默认值
ruby其实没有所谓keyword argument,而是提供一个syntax sugar用hash模拟。但是怎么像Rails的方法那样同时利用命名参数和默认参数值呢?

def image(opt={})
    default_opt = {:height => 25, :width => 10}
    default_opt.merge! opt
end


这个解答了我看RoR book 时候的疑惑,keyword argument 果然是 hash 模拟的。重点学习。

引用

获取metaclass
这也比较常见了,各种动态伎俩的开始
sing = class << self; self; end


没看懂,重点学习。



inject就是reduce,map就是map……后面这句是废话。
源文件管理的惯用法如下
# to import buildscript/javascripttest.rb ...
$:.unshift('buildscript')
require 'javascripttest'
2 楼 buaawhl 2006-09-19  
第一份收藏品。学习中。受益匪浅。great thanks。
另外,源文件/目录/namespace 管理、引入等有什么best practice?
我知道一个require,load 啥的。
还看到有些人实现了ruby import module。

另外,一点疑惑。
引用

(1..10).inject([]){|array, item| array << item}
inject有点难理解,相当于python的reduce和一些FP里的fold。inject的块变量有两个(这里是array和 item),第二个变量(item)用来枚举被inject的集合(这里是(1..10)这个range), 而第一个变量(array)由inject的参数初始化(这里是[],可选),并在block被反复执行时保持持久(相当于静态变量),而item则在每次枚举时被更新为下一个值。是不是越看越晕呼呢?哈哈哈


这个地方虽然没有太看懂,但是感觉和List Comprehension有些像。因为这里产生的结果是一个Array ( like List)。
而Reduce, Fold的结果一般是积累成一个总值。比如,sum。
当然,这只是我的印象。我对ruby inject, Reduce/Fold, List Comprehension了解都不深。
提出疑惑,盼高手解惑。

再看一眼,仿佛这Ruby Inject很符合Reduce/Fold的形式,都是把当前结果和下一个元素作为两个参数继续向下执行。

respond to 确实是个 best practice。

引用

命名参数的默认值
ruby其实没有所谓keyword argument,而是提供一个syntax sugar用hash模拟。但是怎么像Rails的方法那样同时利用命名参数和默认参数值呢?

def image(opt={})
    default_opt = {:height => 25, :width => 10}
    default_opt.merge! opt
end


这个解答了我看RoR book 时候的疑惑,keyword argument 果然是 hash 模拟的。重点学习。

引用

获取metaclass
这也比较常见了,各种动态伎俩的开始
sing = class << self; self; end


没看懂,重点学习。

1 楼 qiezi 2006-09-19  
这么全啊。inject我看了几次没理解,干脆不看了。

ruby函数调用可以省括号,方便是方便,不过一些FP用法也看不见了,这方面python还比较好。

从facet可以看出来,ruby里面使劲往一个类里塞东西还是有传统的。

相关推荐

    ruby的惯用法的使用

    ### Ruby惯用法详解 #### 一、简介 Ruby是一种简单快捷的面向对象的脚本语言,具有丰富的类库和简洁的语法结构。在实际开发过程中,为了提高代码的可读性和可维护性,Ruby社区形成了一系列约定俗成的惯用法(idioms...

    Ruby-Ruby技巧惯用Ruby重构和最佳实践

    在Ruby社区中,惯用法(idioms)和最佳实践(best practices)是提高代码质量的关键。本文将深入探讨Ruby中的关键技巧、重构方法以及遵循的代码风格指南。 一、Ruby技巧 1. 块和迭代器:Ruby中的块(blocks)和...

    Ruby For Rails(英文版)(清晰文字pdf+源码)

    在讲述Ruby知识的过程中,始终从Rails开发实战出发,揭示Rails和Puby之间的微妙关系,阐述Rails自身特有的技术、惯用法和设计理念,并用Rails开发了一个网上音乐店实例。最后还介绍了探索Rails源代码的各种技术,为...

    ruby实战书、代码书.rar

    1. **Ruby idioms**:书中将深入探讨Ruby的惯用法,这些是让代码更简洁、更具Ruby风格的关键。 2. **编程技巧**:如何利用Ruby的特性编写出高效且易于维护的代码,如上下文敏感的语法糖和内建函数的巧妙使用。 3. ...

    Programming Ruby 2nd.pdf

    6. 惯用法和语言扩展:书中还可能会介绍Ruby中的惯用法,以及如何通过元编程进行语言扩展和自定义。这些高级特性是Ruby语言灵活多变的重要原因,也是使Ruby成为一门值得学习的语言的关键特性之一。 7. 历史影响:...

    Ruby For Rails(英文版)(清晰文字pdf)

    通过学习Ruby,开发者可以更容易地理解和运用这些惯用法。 - **扩展性**:Ruby的强大之处在于其高度的灵活性和可扩展性。掌握了Ruby,开发者就能够根据自己的需求灵活地扩展Rails的功能,创造出更加符合业务场景的...

    Ruby for Rails中文版,完整扫描版

    4. Rails技术、惯用法和设计理念:本书还涵盖了Rails特有的技术点、编程惯用法以及Rails的设计哲学,这些都是构建Rails应用时不可忽视的重要方面。 5. 实战项目:作者通过构建一个网上音乐店的实例来展示如何使用...

    basic_assumption:由decent_exposure引入的惯用法的实现,用于在Rails控制器和视图中简明地声明资源

    它实现了一种以声明方式编写某些类型的代码的惯用法。 特别是,这是为了使Rails控制器和视图更整洁。 安装BasicAssumption 这是一颗宝石,通常也是如此: [sudo] gem install basic_assumption 在Rails应用程序...

    atom-idiomatic-comments-css-snippets:原子的惯用CSS注释片段

    3. **惯用法(Idiomatic)**:在编程领域,惯用法是指在特定编程语言或社区中广泛接受的最佳实践,它有助于保持代码的一致性和可读性。 4. **Sublime Text**:Sublime Text是一款流行的文本编辑器,以其速度、简洁...

    技术框架视图

    2. **构架建模惯用法**:为了确保构架模型的一致性和清晰性,通常会采用一套固定的建模惯用法。例如,在用例视图中,用例通常会被命名为描述性的动作短语,以便于理解其功能。 #### 八、结论 综上所述,技术框架在...

    编程新手真言绝对实用

    5. **C抽象惯用法**:在C语言中,有一些约定俗成的做法可以帮助提高代码的可读性和可维护性。 6. **C的抽象范式之OOP**:虽然C语言本身不支持面向对象编程,但可以通过指针等机制来模拟OOP的概念。 7. **C的观点:...

Global site tag (gtag.js) - Google Analytics