lib/ionian/extension/io.rb in ionian-0.6.4 vs lib/ionian/extension/io.rb in ionian-0.6.5

- old
+ new

@@ -10,11 +10,11 @@ # Number of seconds to attempt an IO operation before timing out. # See standard library IO::select. attr_accessor :ionian_timeout # Called automaticallly when the object is extended with #extend. - def self.extended(obj) + def self.extended obj obj.initialize_ionian end # Initialize the Ionian instance variables. # This is called automatically if #extend is called on an object. @@ -44,19 +44,21 @@ # Can be a regular expression specifying capture groups, # or a string specifying the separator or line terminator # sequence. It is possible to use named captures in a # regex, which allows for convienient accessors like # match[:parameter]. - def expression=(exp) + def expression= exp @ionian_expression = exp @ionian_expression = Regexp.new "(.*?)#{expression}" if exp.is_a? String end # Read all data in the buffer. # An alternative to using #readpartial with a large length. def read_all - readpartial 0xFFFF + data = '' + data += readpartial 0xFFFF while has_data? + data end # Read matched data from the buffer. # This method SHOULD NOT be used if #run_match is used. # @@ -81,11 +83,11 @@ # notify: Set to false to skip notifying match listener procs. # skip_select: Skip over the IO::select statement. Use if you # are calling IO::select ahead of this method. # build_methods: Build accessor methods from named capture groups. # Enabled by default. - def read_match(**kwargs, &block) + def read_match **kwargs, &block timeout = kwargs.fetch :timeout, @ionian_timeout notify = kwargs.fetch :notify, true skip_select = kwargs.fetch :skip_select, @ionian_skip_select build_methods = kwargs.fetch :build_methods, @ionian_build_methods @@ -95,14 +97,11 @@ unless skip_select return nil unless ::IO.select [self], nil, nil, timeout end # Read data from the IO buffer until it's empty. - loop do - @ionian_buf << readpartial(0xFFFF) - break unless ::IO.select [self], nil, nil, 0 - end + @ionian_buf << read_all @matches = [] while @ionian_buf =~ exp @matches << $~ # Match data. @@ -111,36 +110,38 @@ # Convert named captures to methods. if build_methods @matches.each do |match| match.names - .map {|name| name.to_sym} - .each {|symbol| match.singleton_class - .send(:define_method, symbol) { match[symbol] } \ - unless match.respond_to? symbol + .map { |name| name.to_sym } + .each { |symbol| + match.singleton_class + .send(:define_method, symbol) { match[symbol] } \ + unless match.respond_to? symbol } end end # Pass each match to block. - @matches.each {|match| yield match} if block_given? + @matches.each { |match| yield match } if block_given? # Notify on_match listeners unless the #run_match thread is active. - @matches.each {|match| notify_listeners match} if notify and not @match_listener + @matches.each { |match| notify_listeners match } \ + if notify and not @match_listener @matches end # Start a thread that checks for data and notifies listeners (do |match, socket|). # Passes kwargs to #read_match. # This method SHOULD NOT be used if #read_match is used. - def run_match(**kwargs) + def run_match **kwargs @match_listener ||= Thread.new do begin while not closed? do matches = read_match **kwargs - matches.each {|match| notify_listeners match } if matches + matches.each { |match| notify_listeners match } if matches end rescue EOFError rescue IOError ensure @match_listener = nil @@ -150,40 +151,37 @@ # Erase the data in the IO and Ionian buffers. # This is typically handled automatically. def purge # Erase IO buffer. - while ::IO.select [self], nil, nil, 0 - readpartial(0xFFFF) - end - + read_all @ionian_buf = '' end # Register a block to be called when #run_match receives matched data. # Method callbacks can be registered with &object.method(:method). # Returns a reference to the given block. # block = ionian_socket.register_observer { ... } - def register_observer(&block) + def register_observer &block @ionian_listeners << block unless @ionian_listeners.include? block block end alias_method :on_match, :register_observer # Unregister a block from being called when matched data is received. - def unregister_observer(&block) - @ionian_listeners.delete_if {|o| o == block} + def unregister_observer &block + @ionian_listeners.delete_if { |o| o == block } block end private # Send match to each of the registered observers. Includes self # as the second block parameter. def notify_listeners match - @ionian_listeners.each {|listener| listener.call match, self} + @ionian_listeners.each { |listener| listener.call match, self } end end end end \ No newline at end of file