Sunday, 23 October 2011

Note FOR Ruby 1.9 之异常,Block

Ruby之异常处理

  Ruby中异常类为Exception,其中$!存储了最后一次异常
begin
rescue <Exception Class> => exc
else #no exception
ensure
end

  除此之外,Ruby还有一种类型的异常是Errno模块,利用Errno.constants和Errno::constant name::Errno查看相关信息.
  retry重新执行begin...end语句,raise重新抛出异常.
  • raise :抛出RuntimeError或者$!
  • raise "Message"
  • raise ZeroDivisionError
  • raise ZeroDivisionError.new("Message“)
  Exception.backtrace

Ruby之Block

  Block不是对象
  Proc,proc和lambda用来从block创建一个对象:
  • a = Proc.new{|i|}
  • b = lambda{|i|}
  • c = proc{|i|}
通过call方法调用,例如a.call(1),3者的一个区别在于Proc在调用是不会检查参数个数是否匹配,而lambda和proc会。
  Ruby中block是闭包(在block创建时能够存储本地变量的值)
1 x = "hello world"
2
3 ablock = Proc.new { puts(x) }
4
5 def aMethod(aBlockArg)
6     x = "goodbye"
7     aBlockArg.call
8 end
9
10 puts x
11 ablock.call
12 aMethod(ablock)
13 ablock.call
14 puts x

  block和实例变量:
1 aClos = lambda{
2     @hello << " baron"
3     puts "in #{self} object of class #{self.class}, @hello = #{@hello}"
4 }
5
6 def aFunc(aClosure)
7      @hello = "hello"
8     aClosure.call
9 end
10
11 class X
12      def y(b)
13           @hello = "I say"
14           puts "in X.y #{self} object of class #{self.class}, @hello = #{@hell o}"
15           b.call
16      end
17 end
18
19 aFunc(aClos)
20
21 x = X.new
22 x.y(aClos)

  block和局部变量:
1 x = 3000
2
3 c1 = lambda{ return x + 100 }
4 c2 = lambda{ |z| return z + 100 }
5 c3 = lambda{ |x| return x + 100 }
6
7 def foo
8      [1, 2].each { |i| c = i }
9      #c在这里不可见
10 end

  defined?用于查看变量类型
  yield:执行传给方法的block
1 def aMethod(str)
2      yield(str)
3 end
4
5 aMethod("Goodbye"){|x| puts(x) }

  方法接受一个带&的参数时,则传入一个block:
1 def aMethod(&p)
2      yield
3 end
4
5 myproc = lambda{puts "hello"}
6 aMethod{puts "goodbye"}
7 aMethod(&myproc)

  block_given?判断有无传入一个block
  {}的block比do...end优先级高:
foo bar do ... end相当于foo (bar) do ... end
foo bar {} 相当于foo (bar{})

  方法返回一个block
1 def calcTax(taxRate)
2      return lambda {
3          |subtotal|
4          subtotal * taxRate
5      }
6 end
7
8 salesTax = calcTax(0.10)
9 vat = calcTax(0.175)
10
11 puts salesTax.call(10)
12 puts vat.call(10)

No comments :

Post a Comment