SitePoint Sponsor

User Tag List

Results 1 to 6 of 6
  1. #1
    SitePoint Zealot
    Join Date
    May 2004
    Posts
    142
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    decorator/composition with iterators

    There is probably a very simple solution to this but I can't seem to find it.

    How can you decorate an iterator with another iterator? For example:

    PHP Code:
    $iterator = new OriginalIterator($result);
    $decoratorIterator = new DecoratorIterator($iterator);
    foreach (
    $decoratorIterator as $item) {
     
    //do something

    What exactly do I need to put into my DecoratorIterator::current() method? I know if DecoratorIterator inherited from OriginalIterator I would just put in a call to parent::current() and then do something with the data but I'm trying to avoid inheritance here so I can pass the OriginalIterator around - or is this the wrong way to do it?

    Any help is appreciated!

  2. #2
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2006
    Location
    Augusta, Georgia, United States
    Posts
    4,194
    Mentioned
    17 Post(s)
    Tagged
    5 Thread(s)
    OrigionalIterator and DecoratorInterator should share the same interface.

    PHP Code:
    interface MyAbtractIterator {

        public function 
    next();
        public function 
    hasNext();
        public function 
    reset();
        

    PHP Code:
    OrigionalIterator implements MyAbtractIterator {

        public function 
    __construct($result) { ... }
        
        public function 
    next() { ... }
        
        public function 
    hasNext() { ... }
        
        public function 
    reset() { ... }


    PHP Code:
    DecoratorIterator implements MyAbtractIterator {

        protected 
    $iterator;

        public function 
    __construct(MyAbtractIterator $iterator) {
        
            
    $this->iterator $iterator;
        
        }
        
        public function 
    next() {

                     
    // change behavior here
        
            
    return $this->iterator->next();
        
        }
        
        public function 
    hasNext() {

                   
    // change behavior here
        
            
    return $this->iterator->hasNext();
        
        }
        
        public function 
    reset() {

                   
    // change behavior here
        
            
    return $this->iterator->reset();
        
        }



  3. #3
    SitePoint Wizard Ren's Avatar
    Join Date
    Aug 2003
    Location
    UK
    Posts
    1,060
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    SPL has an OuterIterator interface *, meant for such cases, which implement for decorating iterators...
    PHP Code:
    <?php

        
    class DecoratingIterator implements OuterIterator
        
    {
            protected 
    $inner;

            function 
    __construct(Iterator $inner) { $this->inner $inner; }
            function 
    next() { $this->inner->next(); }
            function 
    rewind() { $this->inner->rewind(); }
            function 
    key() { return $this->inner->key(); }
            function 
    current() { return $this->inner->current(); }
            function 
    valid() { return $this->inner->valid(); }

            function 
    getInnerIterator() { return $this->inner; }
        }

        class 
    SquaringIterator extends DecoratingIterator
        
    {
            function 
    current()
            {
                
    $r parent::current();
                return 
    $r $r;
            }
        }

        
    $di = new SquaringIterator(new ArrayIterator(array(012)));

        foreach(
    $di as $v)
            echo 
    $v"\n";


    * this should've been a class, imo, would save having to create a class.

  4. #4
    SitePoint Zealot
    Join Date
    May 2004
    Posts
    142
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    thanks guys!

  5. #5
    SitePoint Zealot
    Join Date
    May 2008
    Location
    Montreal
    Posts
    155
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Also see the SPL's IteratorIterator, it implements the boilerplate that you would otherwise need to do manually. Also note that in some cases it acts strangely.

  6. #6
    SitePoint Zealot
    Join Date
    May 2004
    Posts
    142
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Peter Goodman View Post
    Also see the SPL's IteratorIterator, it implements the boilerplate that you would otherwise need to do manually. Also note that in some cases it acts strangely.
    Ah, I knew I'd heard about that somewhere! Thanks to everyone!


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
  •