SitePoint Sponsor

User Tag List

Results 1 to 6 of 6
  1. #1
    SitePoint Guru
    Join Date
    May 2003
    Location
    virginia
    Posts
    988
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Eclipse Loop/LoopManipulator uses?

    I've used the Eclipse library before and messed around with the Loop Manipulator (and Watchers etc..) a little. But to be honest I could never understand how to put it to use (and re-use!). I know there is something I'm not getting... I thought I'd just ask to find out if any of you could give me some good examples of what you can do with it.

    Thanks in advance!

    Matt

  2. #2
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Quote Originally Posted by mwmitchell
    I thought I'd just ask to find out if any of you could give me some good examples of what you can do with it.
    It's not really very flexible and seems to be there just to shorten the client code a little. Really there are two ways to work on container information. Have the container output some kind of iterator...
    PHP Code:
    $result = &$connection->select($query);
    while (
    $row $result->next()) {
        
    $table->write_line($row);

    ...or have all of the looping handled internally...
    PHP Code:
    $connection->select($query$table); 
    The second version is looks cleaner because it calls the write() method internally. The iterator is more flexible though; you could pass the iterator off to another class to do the work for example. The downside of the iterator is that it exposes another class and makes the client code longer (as above). You have to pull data from an iterator, whereas passing the table display object in means that data is pushed into it.

    The disadvantage of passing in a listener ($table) is that the main class is now coupled to the interface of the receiver of that listener. The client code is shorter, but you have little choice over the interface. All of the control is now in the receiver class as well. One solution to this is for the receiver to pass itself into the listener when it calls it with it's event. This allows the listener to choose the work it does on the original receiver. This is called the visitor pattern. It means that the two classes are even more tightly coupled though.

    Basically, if the navigation to change or is complex (walking a tree for example) then use a visitor as that way you will avoid repeating and exposing a system that is likely to change. If the navigation of the data is unlikely to change, or needs to be under the control of the caller, then it is better to expose it as an iterator. This is the usual situation with database rows.

    The Eclipse library basically supplies a sort of prebuilt visitor (the manipulator) for you to subclass. Sounds like the worst of both worlds to me seeing as the iterator is already exposed by the library. Especially as you can rewrite the iterator example like this...
    PHP Code:
    $table->write($connection->select($query)); 
    You can also add decorators to the iterator this way to manipulate the data as it passes through...
    PHP Code:
    $table->write(new EmailObfuscator(
            
    $connection->select($query))); 
    Overall it's a good little library though, so I am not knocking it.

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  3. #3
    SitePoint Guru
    Join Date
    May 2003
    Location
    virginia
    Posts
    988
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Marcus,

    Thanks for the reply and all of the mind bending information! I think I understand what you are saying in general. But I don't know what you mean when you say "navigation". Can you explain this?

    Also, would you mind posting an example of how your table class (listener) would look, and how you use decorators to manipulate the data? It'd help me a lot to see some really basic code... If you have the time that is!

    Thanks,

    Matt

  4. #4
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Quote Originally Posted by mwmitchell
    Thanks for the reply and all of the mind bending information! I think I understand what you are saying in general. But I don't know what you mean when you say "navigation". Can you explain this?
    Suppose that you were iterating through a list. That table gets modified so that now you only want a filtered version of that list put out. With the iterator approach you have to change both the container class and the iterator. With a listener based approach only one and you can simply have the container call different methods for different types of data. A good example of this kind of change is parsing. The XML SAX parsers usually take a listener approach (push) because of all of the different token types. If you pull the data you must figure out the incoming token yourself.

    Quote Originally Posted by mwmitchell
    Also, would you mind posting an example of how your table class (listener) would look, and how you use decorators to manipulate the data? It'd help me a lot to see some really basic code... If you have the time that is!
    I don't really, but it beats real work .
    PHP Code:
    class Table {
        ...
        function 
    paint(&$iterator) {
            if (! (
    $row $iterator->next())) {
                return;
            }
            
    $this->paintHeader($row);
            do {
                
    $this->paintRow($row);
            while (
    $row $iterator->next());
            
    $this->paintFooter();
        }
        ...

    Here is a possible decorator...
    PHP Code:
    class LongLineTruncator {
        var 
    $_iterator;

        function 
    LongLineTruncator(&$iterator) {
            
    $this->_iterator = &$iterator;
        }
        function 
    next() {
            
    $line $this->_iterator->next();
            if (! isset(
    $line)) {
                return 
    null;
            }
            return 
    $this->_truncateLine($line);
        }
        function 
    _truncateLine($line) { ... }

    Usage...
    PHP Code:
    $table = &new Table();
    $table->paint(new LongLineTruncator($iterator)); 
    I've skipped the details. Is this OK?

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  5. #5
    SitePoint Addict been's Avatar
    Join Date
    May 2002
    Location
    Gent, Belgium
    Posts
    284
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Suppose that you were iterating through a list. That table gets modified so that now you only want a filtered version of that list put out. With the iterator approach you have to change both the container class and the iterator. With a listener based approach only one and you can simply have the container call different methods for different types of data.
    Seems like that is what the RowLoopManipulator and RowLoopManipulatorWatcher were intended for in Eclipse?
    The LongLineTruncator could go something like this:
    PHP Code:
    class LongLineTruncator extends RowLoopManipulator
     
    {
         var 
    $_maxLineLength;
     
         function 
    LongLineTruncator($maxLineLength 80)
         {
             
    $this->_maxLineLength $maxLineLength;
             
    $this->RowLoopManipulator();
             
    $watcher =& $this->addWatcher('line');
             
    $watcher->register('truncateLine');
         }
     
         function 
    truncateLine(&$row)
         {
             
    $row['line'] = substr(0$this->_maxLineLength$row['line']);
         }
     
         function 
    current(&$row$index)
         {
             
    parent::current($row$index);
             echo 
    '<td>'$row['line'], '</td>';
         }
     }
     
     class 
    TablePrinter extends LoopManipulator
     
    {
         var 
    $_linePrinter;
     
         function 
    TablePrinter(&$linePrinter)
         {
             
    $this->linePrinter =& $linePrinter;
         }
     
         function 
    prepare()
         {
             echo 
    '<table>''<tr>';
             
    //...
         
    }
     
         function 
    current(&$line$index)
         {
             
    $this->_linePrinter->current(array('line'$line), $index);
         }
     
         function 
    between($index)
         {
             echo 
    '</tr><tr>';
         }
     
         function 
    finish($total)
         {
             echo 
    '</tr>''</table>';
             
    //...
         
    }
     }
     
    $i =& new WhateverIterator($whatever);
     
    $m =& new LongLineTruncator($max_line_length);
     
    Loop::run($i, new TablePrinter($m)); 
    It's a bit awkward because of the fact that you must turn the scalar string representing a line into a hash (the watchers are keyname based).
    Also, I'm not too sure about the inheritance thing in there, I tend to look at it as being an interface...
    But bearing in mind that Eclipse is a bit of an 'older' library that hasn't been worked on since 3.10 (Haven't looked at the CE version at sourceforge in a long time), I must say that the Loop is quite a thought through and funky component... Wait a minute, I'm having a vision here... Maybe the LoopManipulator... is... a... pattern... ?
    Ok, tongue in cheek here, I'm hardly in a position to make a qualified judgement about that , but, Those prepare(), current() and finish() methods, I see them popping up all over the place, albeit in different names: header() footer(), paintHeader() paintFooter(), renderHeader() renderFooter() renderContent(), etc...
    Per
    Everything
    works on a PowerPoint slide

  6. #6
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Quote Originally Posted by been
    Seems like that is what the RowLoopManipulator and RowLoopManipulatorWatcher were intended for in Eclipse?
    From private correspondence at the time with Vincent, yes that is exactly what it is for. It only really works for tabular data though. This is what I mean about Eclipse adding this as a convenience method for shorter client code. With Eclipse you have a choice of systems, but I am not sure it was worth complicating the library with it. I don't know, you decide?

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •