From: Eric Mahurin Date: 2005-07-22T01:07:19+09:00 Subject: [ANN] cursor-0.8 I just released a complete overhaul of the cursor package: http://rubyforge.org/projects/cursor/ Here are the various types of Cursor classes in this release: Cursor Cursor::Buffered Cursor::IO Cursor::Indexed Cursor::Lined Cursor::Linked Cursor::Reversed Cursor::Shifting Cursor::Split Cursor::Circular Cursor::Circular::Indexed Cursor::Circular::Linked Cursor::Circular::Shifting Cursor::Circular::Split So far, I've only optimized Cursor::IO. The rest of the various datastructures have lots of optimization to go. If any of you are iterested, the testing method I used has been extremely useful at finding bugs and debugging - random testing. I compared objects in the classes above against each other applying a random sequence of methods. It also is useful for generating examples. Here is the documentation for the base class Cursor: An object in this Cursor class can be best thought of as a cursor in a text editor. Many of the same operations apply - insert, delete, replace, copy, paste, move, goto begin/end, mark position, goto mark, etc. Unlike a text editor, this class can operate on variety of data, not just characters and strings. It is up to the derived classes to deal with what type of data is stored (i.e. characters, arbitrary array objects) and how it is stored (in an Array, String, IO, linked list, mapping to another Cursor, etc). The minimal a derived class has to implement to be able to get all of the features below is inserting and deleting an element (both directions). Various categories of methods are described in the paragraphs below. The single element methods are listed below. The suffix Next/Prev means operate after/before the cursor and move the cursor in the same direction. The suffix After/Before means operate after/before the cursor and leave the cursor in place. The ? suffix looks what is being written over or deleted and returns it instead of true (the reads are like ? versions of skips). The ! suffix forces the operation by doing an insert instead of overwrite at the beginning/end. When any of these operations fail (at beginning/end or a mismatch) nil is returned. read1next, read1prev, read1after, read1before, skip1next, skip1prev, skip1after, skip1before, write1next, write1prev, write1after, write1before, write1next!, write1prev!, write1after!, write1before!, write1next?, write1prev?, write1after?, write1before?, delete1after, delete1before, delete1after?, delete1before?, insert1before, insert1after, scan1next, scan1prev, modify1next, modify1prev, Basic methods that operate on element sequences are listed below. These are all bidirectional, can hold the cursor in place, and some may be able to delete/insert. The ! suffix operates until the beginning/end. The element sequences are passed/returned in Array/String like things. The methods these sequences need are #<< and/or #[]. new_data controls the default sequence returned (but another object that responds to #<< can be passed in instead). Sequences to be written/scanned with need to respond to #[] (scanning requires this return something responding to #==). read, read!, skip, skip!, write, write?, scan, scan_until, scan_partial, modify The methods below deal with numeric positions (a pos) to represent the cursor location. A non-negative number represents the number of elements from the beginning. A negative number (including -0.0) represents the location relative to the end. Also included in this list below is prop for manipulating properities for the current cursor location. One typical use is for tracking line and column numbers. pos, pos=, to_i, prop, to_s, The position methods below use a Cursor object (Cursor::Position in the base class) to hold the position rather than simply a numeric position. These position objects hold a pos and whatever is in prop. Also, the pos in these objects adjust based on insertions and deletions. It is preferrable to use these position objects over numeric positions because a) derived classes may have a more efficient means of holding a position (i.e. linked list could hold a node reference), b) they may trigger things like buffering in derived classes, c) they hold what�s in prop, d) they adjust with insert/delete, e) when the numeric positions can�t be implemented these methods still may, and f) the covenience of saving and possibly restoring position before/after executing a code block is available (should be implementable before any of the others). position, position=, position?, position!, close, closed? Queries about current position relative to another position: #<=>, #- Return a remote position: #+, succ, pred, begin, end Access the entire collection: empty?, length/size, data, replace Random access: #[]/slice, slice!, #[]=, #<<, #>> Enumerable: each, collect!/map! The best way to get examples/demos of the methods and the classes is to use the cursor/test_cursors.rb and cursor/test_circulars.rb scripts. ____________________________________________________ Start your day with Yahoo! - make it your home page http://www.yahoo.com/r/hs