Wednesday, 26 October 2011

Note FOR Ruby 1.9 之线程,调试和单元测试

Ruby之线程

  创建一个线程Thread.new, 主线程为Thread.main.Ruby中线程有5中状态:(nil和false状态在inspect下显示为dead,可以用status方法查看线程状态)
  • run: 线程正在执行
  • sleep: sleep或等待IO
  • aborting
  • false: 线程正常结束
  • nil: 线程异常结束
  线程的执行:
words = ["hello", "world", "goodbye", "mars"]
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Thread.new {
    words.each{ |word| puts word }
}

Thread.new {
    numbers.each{ |number| puts number }
}
  以上代码,两个线程将得不到机会执行.利用join方法,使线程调用者挂起,直到join的线程结束
words = ["hello", "world", "goodbye", "mars"]
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
chars = ["a", "b", "c", "d"]

Thread.new {
    words.each{ |word| puts word }
}.join

Thread.new {
    numbers.each{ |number| puts number }
}.join

chars.each{ |ch| puts ch }
  这样线程变成有序执行了,正确的方法应该如下:
words = ["hello", "world", "goodbye", "mars"]
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

thread1 = Thread.new {
    words.each{ |word| puts word }
}

thread2 = Thread.new {
    numbers.each{ |number| puts number }
}

[thread1, thread2].each { |t| t.join }
  线程优先级:(Thread.pass把执行时间让给其他线程), 设置priority属性,main的priority为0.
  Thread.stop线程挂起, run线程运行
  Mutex类:需要require 'thread'
semaphore = Mutex.new

a = Thread.new {
    semaphore.synchronize {
        1000000.times{ $i += 1 }
    }
}

b = Thread.new {
    semaphore.synchronize {
        1000000.times{ $i += 1 }
    }
}


  Ruby对语句写成多行可能会出现意想不到的结果:
x = (10 +
(2*4))
x = 18
x = (10
+ (2*4))
x = 8
x = (10 \
+ (2*4))
x = 18
  Ruby之irb: irb --help

Ruby之调试

ruby -r debug test.rb

Ruby之单元测试

  1. require 'test/unit'
  2. 继承Test::Unit::TestCase
  3. 方法名要以test开始
  4. setup:在测试代码之前执行
  5. teardown:在测试代码之后执行
附:单元测试相关函数:
  • assert(boolean, message=nil)
  •   Asserts that boolean is not false or nil.
  • assert_block(message="assert_block failed.") {|| ...}
  •   The assertion upon which all other assertions are based. Passes if the block yields true.
  • assert_equal(expected, actual, message=nil)
  •   Passes if expected == +actual.
  • assert_in_delta(expected_float, actual_float, delta, message="")
  •   Passes if expected_float and actual_float are equal within delta tolerance.
  • assert_instance_of(klass, object, message="")
  •   Passes if object .instance_of? klass
  • assert_kind_of(klass, object, message="")
  •   Passes if object .kind_of? klass
  • assert_match(pattern, string, message="")
  •   Passes if string =~ pattern.
  • assert_nil(object, message="")
  •   Passes if object is nil.
  • assert_no_match(regexp, string, message="")
  •   Passes if regexp !~ string
  • assert_not_equal(expected, actual, message="")
  •   Passes if expected != actual
  • assert_not_nil(object, message="")
  •   Passes if ! object .nil?
  • assert_not_same(expected, actual, message="")
  •   Passes if ! actual .equal? expected
  • assert_nothing_raised(*args) {|| ...}
  •   Passes if block does not raise an exception.
  • assert_nothing_thrown(message="", &proc)
  •   Passes if block does not throw anything.
  • assert_operator(object1, operator, object2, message="")
  •   Compares the +object1+ with +object2+ using operator. Passes if object1.send(operator, object2) is true.
  • assert_raise(*args) {|| ...}
  •   Passes if the block raises one of the given exceptions.
  • assert_raises(*args, &block)
  •   Alias of assert_raise. (Deprecated in Ruby 1.9, and to be removed in 2.0).
  • assert_respond_to(object, method, message="")
  •   Passes if object .respond_to? method
  • assert_same(expected, actual, message="")
  •   Passes if actual .equal? expected (i.e. they are the same instance).
  • assert_send(send_array, message="")
  •   Passes if the method send returns a true value.
  • assert_throws(expected_symbol, message="", &proc)
  •   Passes if the block throws expected_symbol
  • build_message(head, template=nil, *arguments)
  •   Builds a failure message. head is added before the template and argu-ments replaces the ’?’s positionally in the template.
  • flunk(message="Flunked")
  •   flunk always fails.

No comments :

Post a Comment