如果有一段代码,类似于一个巨大的Case,例如:
report[:event_name] = case vals[0]
when 1 then report[:size] = vals[1]; 'FTP Upload Attempt'
when 2 then report[:connect_time] = vals[1]; report[:download_time] = vals[2]; report[:size] = vals[3]; report[:reason] = vals[4]; 'FTP Upload End'
when 10 then report[:duration] = vals[1]; 'MOC Attempt'
when 11 then report[:reason] = vals[1]; 'Call End'
when 530 then 'Stop Test'
when 528, 529 then 'Stop Logging'
#......许多类似的代码
else
format("event 0x%08x", vals[0])
end
我们怎么去做比较方便,容易扩充又是Ruby的方式呢?
两种方法:
第一种,用Proc.new
首先定义一个Hash表类似于下面:
@event_callers ||= {
10 => Proc.new { |m, r, v| r[:duration] = 10; "MOC Attempt" },
11 => Proc.new { |m, r, v| r[:reason] = v[1]; 'Call End' }
... => Proc.new ....
}
然后case就可以省略,类似于下面即可:
proc = @event_callers[vals[0]]
report[:event_name] = proc ? proc.call(msg, report, vals) : "0x" + sprintf("%08x", vals[0])
第二种方法,用Block实现:
首先定义一个方法:
def define_event(event_code, &block)
@event_callers ||= {}
@event_callers[event_code] = block
end
然后用户也好,你自己写代码也好,可以用define_event定义code和block的对应关系:
define_event 10 do |m, r, v|
p "define_event:", m, r, v
end
Case语句可以写成:
@event_callers[10].call(msg, report, vals)