Class: Expect::Matcher
- Inherits:
-
Object
- Object
- Expect::Matcher
- Defined in:
- lib/expect/matcher.rb
Overview
驱动一次单会话或多会话匹配,管理模式优先级、EOF 和共享期限,不接管 IO 所有权。 调度只在扫描、回调和 IO 操作之间检查期限,不强行中断用户代码或单次正则计算。
Instance Method Summary collapse
-
#initialize(patterns, timeout, deadline: nil) ⇒ Matcher
constructor
固定本次参与的会话及初始期限;已处理 EOF 的会话仅从本次等待中移除。.
-
#run ⇒ Object
运行匹配状态机;内部 :retry 表示继续循环,最终返回一个 Result。.
Constructor Details
#initialize(patterns, timeout, deadline: nil) ⇒ Matcher
固定本次参与的会话及初始期限;已处理 EOF 的会话仅从本次等待中移除。
8 9 10 11 12 13 14 15 16 17 18 19 |
# File 'lib/expect/matcher.rb', line 8 def initialize(patterns, timeout, deadline: nil) @patterns = patterns @sessions = patterns.sessions @timeout = Expect.duration(timeout) # 相对期限可因接收或 continue 重算,总期限始终固定;两者共用单调时钟。 @hard_deadline = deadline @deadline = next_deadline @handled_eof = [] @stalled_matches = {} @polled = false @expired_eof_continuation = false end |
Instance Method Details
#run ⇒ Object
运行匹配状态机;内部 :retry 表示继续循环,最终返回一个 Result。
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/expect/matcher.rb', line 22 def run @relay_buffers = {} @sessions.each do |session| buffer = session.__send__(:interaction_buffer) if buffer # 转义回调中的显式匹配临时接管读取,先消费转接已经预读的尾部。 @relay_buffers[session] = buffer session.__send__(:interaction_buffer=, nil) session.__send__(:restore_relay_buffer, buffer) buffer.clear end session.__send__(:reset_result) end loop do # 先消费已缓冲的匹配,再处理 EOF,最后读取;避免进程退出时丢失最后一个匹配。 result = if !@expired_eof_continuation && !hard_expired? && (matched = find_match) handle_match(*matched) elsif (session = unhandled_eof) handle_eof(session) elsif @expired_eof_continuation || hard_expired? handle_timeout else read_next end return result unless result == :retry end ensure # 嵌套 expect 即使异常退出,也要把未消费尾部还给原 Relay 的同一个缓冲对象。 @relay_buffers.each do |session, buffer| buffer.replace(session.clear_buffer) session.__send__(:interaction_buffer=, buffer) end end |