Functional Ruby

本文是函数式Ruby编程的学习笔记。

 

1.Ruby中的迭代方法(如each, map)需要与Block配合使用,那么如何获得Block呢?

  • 直接使用{}或do ... end
  • 将Proc或Method对象转化为Block. &proc_name/&:method_name/&method(:method_name) => block

获得Proc或Method对象的几种方式:

注意:对于无参方法f,可以直接用&:f将其转化为block,但对于有参方法f(如上图),需要将其显示地转化为Method对象,&method(:f) .

 

2. &:method_name 与 &method(:method_name)的区别

 1 class A
 2     def f
 3         self
 4     end
 5 end
 6 
 7 as = Array.new(3) {A.new}
 8 
 9 as.map(&:f) #(a)
10 as.map(&A.new.method(:f)) #(b)

(a) as.map(&:f) 相当于 as.map {|a| a.f} ,也就是对于as中的每个对象调用方法f,所以第9行会得到as中每个对象的地址。

(b) as.map(&A.new.method(:f)) 相当于 as.map { f(a) } ,则是将as中的每个对象作为参数传给方法f,而方法f是无参的,所以第10行会报 wrong number of arguments (given 1, expected 0) (ArgumentError) 错误。

 

3.irb中的访问控制

在irb中输入以下代码

 1 class A
 2     def f
 3         self
 4     end
 5 end
 6 
 7 as = Array.new(3) {A.new}
 8 
 9 def f1
10     1
11 end
12 
13 as.map(&:f1) #(a)

按照2中的总结 as.map(&:f1) 相当于 as.map {|a| a.f1} ,但是对象a并没有方法f1,第13行应该会报错,但在irb中第13行却返回 [1, 1, 1] ,怎么回事呢?如果你将以上代码复制到一个文件中再执行,就会报  private method `f1' called for #<A:0x00000002913b18> (NoMethodError) 错误,提示f1是私有方法,as中的对象并没有方法f1,将f1设置为public方法后(public方法可以被任何对象调用),第13行同样会返回 [1, 1, 1]。综上,irb中第13行返回 [1, 1, 1]应该是对方法的访问控制没有实现好。

posted @ 2016-10-04 18:37  fosmj  阅读(182)  评论(0编辑  收藏  举报