C08 Exceptions
1. 定义一个Exception
class MyException < StandardError
def initialize(info)
super(info)
end
end
2. 抛出并且捕获一个异常
require 'my_exception'
def raise_exception
raise MyException.new("ERROR occurs!!!")
end
begin
raise_exception()
rescue MyException => e
print(e.backtrace.join("\n"))
end
3. ensure和else
require 'my_exception'
def raise_exception_bycondition(num)
if num != 5
puts("num = #{num}")
elsif num == 5
puts("num = 5")
raise MyException.new("Num == 5!!!")
end
end
print("Input a number:")
end_num = Integer(gets)
begin
for i in 1..end_num
raise_exception_bycondition(i)
end
rescue MyException => e
print(e.backtrace.join("\n"))
puts()
else
puts("No MyException!")
ensure
puts("Alwasy ouput this sentense!")
end
4. Retry
require 'my_exception'
def raise_exception_bycondition(raiseornot)
if raiseornot
raise MyException.new("Raise MyException!")
else
puts("Don't raise MyExcetpion!")
end
end
$raiseornot = true
begin
raise_exception_bycondition($raiseornot)
rescue MyException => e
print(e.backtrace.join("\n"))
puts()
$raiseornot = false
retry
end
5. throw and catch
def prompt_and_get(prompt)
print prompt
res = readline.chomp
throw :quit_requested if res == "!"
res
end
catch :quit_requested do
name = prompt_and_get("Name: ")
age = prompt_and_get("Age: ")
sex = prompt_and_get("Sex: ")
puts("name: #{name} -- Age: #{age} -- Sex: #{sex}")
end
6. caller在raise时的使用
require 'my_exception'
def raise_exception
raise MyException, "ERROR occurs!!!", caller[1..-1]
end
def raise_exception2
raise_exception
end
begin
raise_exception2()
rescue MyException => e
print(e.backtrace.join("\n"))
puts()
end
结果显示是:
caller_sample.rb:12
C09 Modules
1. Module
#module1.rb
module Module1
Name = "Module1 Name"
def Module1.info
"Module1"
end
end
#module2.rb
module Module2
Name = "Module2 Name"
def Module2.info
"Module2"
end
end
#module_sample.rb
require 'module1'
require 'module2'
puts(Module1.info)
puts(Module2.info)
puts(Module1::Name)
puts(Module2::Name)
2. Mixin
#observable_mixin.rb
module Observable
def observers
@observer_list ||= []
end
def add_observer(obj)
observers << obj
end
def notify_observers
observers.each {|o| o.update }
end
end
#weather_info.rb
require 'observable_mixin'
class WeatherInfo
include Observable
end
class WeatherShowForm1
def update
puts 'Weather update1'
end
end
class WeatherShowForm2
def update
puts 'Weather update2'
end
end
winfo = WeatherInfo.new()
winfo.add_observer(WeatherShowForm1.new)
winfo.add_observer(WeatherShowForm2.new)
winfo.notify_observers()
3. 名字查找顺序
Ruby looks first in the immediate class of an object, then in the mixins included into that class, and then in superclasses and their mixins. If a class has multiple modules mixed in, the last one included is searched first.