E
Eric Mahurin
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 #=3D=3D).
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=3D, to_i, prop, to_s,
The position methods below use a Cursor object
(Cursor:osition 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=92s in prop, d) they adjust
with insert/delete, e) when the numeric positions can=92t 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=3D, position?, position!, close, closed?
Queries about current position relative to another position:
#<=3D>, #-
Return a remote position: #+, succ, pred, begin, end
Access the entire collection: empty?, length/size, data,
replace
Random access: #[]/slice, slice!, #[]=3D, #<<, #>>
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.
=09
____________________________________________________
Start your day with Yahoo! - make it your home page=20
http://www.yahoo.com/r/hs=20
=20
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 #=3D=3D).
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=3D, to_i, prop, to_s,
The position methods below use a Cursor object
(Cursor:osition 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=92s in prop, d) they adjust
with insert/delete, e) when the numeric positions can=92t 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=3D, position?, position!, close, closed?
Queries about current position relative to another position:
#<=3D>, #-
Return a remote position: #+, succ, pred, begin, end
Access the entire collection: empty?, length/size, data,
replace
Random access: #[]/slice, slice!, #[]=3D, #<<, #>>
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.
=09
____________________________________________________
Start your day with Yahoo! - make it your home page=20
http://www.yahoo.com/r/hs=20
=20