[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Re: [ANN] cursor-0.5

Eric Mahurin

5/20/2005 2:06:00 PM


--- Aleksi <foobar@fuzzball.org.net> wrote:
> Eric Mahurin wrote:
> > I just released the gem package cursor-0.5 on rubyforge:
>
> Sounds interesting.
>
> > The is an initial release that focuses on the functionality
> and
> > tries to give a robust API (mimics stuff in IO,
> Array/String,
> > is Enumerable, is Rangable, is Comparable). The derived
> > classes are minimally implemented and not very efficient
> (and
> > some cases terribly inefficient).
>
> Could you tell a bit more in detail how does your goal differ
> from let's
> say MetaRuby.
>
> Not this MetaRuby
>
> http://www.zenspider.com/Languages/Ruby/Met... but
> instead this
>
> but original one
>
> http://raa.ruby-lang.org/project...
>
> which source code you can apprently view here
>
> http://raa.ruby-lang.org/gonzui/marku...
>
> and which quite old source balls might be here
>
> http://artengine.ca/matju...
>
> The concept of Hollowness comes through as similar goal in
> yours and
> Matju's work.

I'm not sure what Hollowness is.

What I did is quite different than the above. The above looks
to make an abstraction of Array/String I think - basing
everything off of a few routines - length, get(i), put(i), etc.

If you wanted to compare what I did to an existing Ruby class,
it is most like an IO. Just like an IO has current position in
a file and reads/writes at that point, a Cursor represents a
position into some sequential data structure and read/writes
(and inserts/deletes) at that point. Also take a look at the
iterator package for reference:

http://aeditor.rubyforge.org...

For the Cursor class, there are only 2 very fundamental
operations that the base class can do everything off of -
delete an element (before or after) and insert an element
(before or after). These 2 methods are protected and the
fundamental operations from the user of this class are get and
put which can do things like putc, getc, puts, gets, read,
write from IO in addtion to other stuff (insertion and
deletion). All other methods are based on these get/put
methods - random access, length, begin/end, marking/setting a
position, etc.

A unique feature compared to other external iterators is the
way the end/begin of sequence is handled. Instead of the get
simply returning nil (would have problems with nil elements) or
requiring a has_next? call, get/put can take a block that is
executed when the end/begin is found. This block can simply
set some eof flag or even give more data to trick it into
thinking that you are not at the end/begin. I use this last
tricking capability to easily accomplish buffering - when the
buffer cursor reaches its end, it reads from the input cursor
to get more data. Comparing to the iterator package (like the
C++ iterators), this is how you would do a simple iteration of
the elements:

while iter.has_next?
element = iter.current
# do something with element
iter.next
end

You can do it the same type of way in Cursor (using eof?, [],
and succ!), but here is a better way (one method call instead
of 3):

continue = true
loop do
element = cursor.get { continue = nil }
break unless continue
# do something with element
end

or if you know valid elements can't be nil you can do it the IO
way:

while element = cursor.get
# do something with element
end


To give you an idea of what can be done, here are the docs for
get (put has a similar range of capabilities):

---------

get(length=nil,flags=Next) {|len| ...}

Get a single element or a sequence of them.

length can be nil (get one element - like IO#getc), a positive
number (get a sequence of that many elements - like IO#read), 0
(get all remaining - like IO#read), a negative number (get all
but that many), or what data_class says (get a sequence up
until it finds a match to length - like IO#gets).

The observed bits in flags are Reverse (read before instead of
after the cursor), Hold (don?t move the cursor), Ignore (just
return true or a count instead of the value), and Delete
(delete the element or sequence while retrieving it).

If there is anything left, either nil (no code block) or the
result from code block is returned. This code block could set
some variable(s) to signify it is done or return data from some
other source to make it look as though it is not done. When
returning more data, it should return it in a String or Array
of up to len elements.

-----------

Here are the current cursor classes I have:

Cursor - base class
Cursor::Position - used for marking positions
Cursor::Test - minimal override to test base class
Cursor::Indexed - make a cursor from a String/Array
Cursor::Reversed - reverses direction of a cursor
Cursor::Buffer - inexpensive insert/delete
Cursor::Buffered - buffers input and/or output cursors
Cursor::IO - make a cursor out of an IO





Yahoo! Mail
Stay connected, organized, and protected. Take the tour:
http://tour.mail.yahoo.com/mai...



1 Answer

Simon Strandgaard

5/21/2005 7:40:00 AM

0

On 5/20/05, Eric Mahurin <eric_mahurin@yahoo.com> wrote:
[snip]
> Here are the current cursor classes I have:
[snip]

Please add a few example files to your package on how to
use each of these classes.

Your Cursor#get and Cursor#put methods looks a bit longish.

Having + and - as public methods is maybe dangerous, you
risk not closing the instances after usage.

--
Simon Strandgaard