Hej everybody,

I had a chat with Stefan about his Traits/Grafts RFC and he suggested we
should rather continue a discussion here.

I really liked to see the Grafts proposal. In traits and regular
inheritance the implementation code of several entities is somehow mixed
and as a result one entities code can break another entities code. The
great thing about Grafts is that the implementation is not mixed. Grafts
are completely encapsulated entities with their own state. I think in
many cases where inheritance or traits seem tempting, complete
encapsulation is actually the cleaner solution.

The Grafts proposal, however, suffered a little from being born out of
traits, I think. Something similar to Grafts is already possible in
current php, but it is not very beautiful. If we start from there
however, Grafts could become very helpful syntactic sugar. Let's look at
current PHP first:

class Counter {
  private $cnt = 0;
  public function inc() {
    $this->cnt++;
    return $this;
  }
  public function reset() {
    $this->cnt = -1;
    $this->inc();
    return $this;
  }
  public function current(){
   return $this->cnt;
    return $this;
  }
}
class QueueTicketPrinter{
  private $counter;
  public __construct(){
    $this->counter = new Counter();
  }
  public function takeNumber(){
    print 'your number is ".$this->counter->current();
    $this->counter->inc();
  }
  public function current(){
    $this->counter->current();
  }
  public function reset(){
    $this->counter->reset();
  }
}

This is a lot of code in QueueTicketPrinter for that it mostly reuses
Counter. Grafts as syntactic sugar could make it look as short as:

class QueueTicketPrinter{
  use Counter as private $counter{
    public current();
    public reset();
  }
  public function takeNumber(){
    print 'your number is ".$this->counter->current();
    $this->counter->inc();
  }
}

However a problem remains. The methods of counter return $this (aka
implement a fluent interface). One idea that came to my mind to solve
this problem: PHP could provide a keyword fluent that replaces a methods
return value to form a fluent interface i.e. return $this:

class QueueTicketPrinter{
  use Counter as private $counter{
    public fluent current();
    public fluent reset();
  }
  public function takeNumber(){
    print 'your number is ".$this->counter->current();
    $this->counter->inc();
  }
}

The keyword fluent ignores whatever value the Counter function may
return and returns an the instance of QueueTicketPrinter instead.

Finally, can somebody provide a sensible use case for traits, that
cannot be solved with Grafts? I am sure there is, but I am currently
lacking one.

Cheers

Christopher

P.S. Hope that stupid post before does not make me seem too much like it ;).

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to