配列っぽいクラスを書いてみる
http://d.hatena.ne.jp/hope-echoes/20080424/1209031875 の続き。
PHP: ArrayObject - Manual を参考に実装してみる。
<?php class Ary implements ArrayAccess, Countable, IteratorAggregate { public function __construct($values = array()) { $this->values = $values; } // {{{ ArrayAccess public function offsetExists($offset) { return isset($this->values[$offset]); } public function offsetGet($offset) { if (!array_key_exists($offset, $this->values)) { throw new OutOfBoundsException; } return $this->values[$offset]; } public function offsetSet($offset, $value) { if (is_null($offset)) { $this->values[] = $value; } else { $this->values[$offset] = $value; } } public function offsetUnset($offset) { if (array_key_exists($offset, $this->values)) { unset($this->values[$offset]); } } // - ArrayAccess }}} // {{{ Countable public function count() { return count($this->values); } // - Countable }}} // {{{ IteratorAggregate public function getIterator() { return new AryIterator($this->values); } // - IteratorAggregate }}} protected $values; } class AryIterator implements ArrayAccess, Countable, SeekableIterator { public function __construct($values = array()) { $this->values = $values; $this->rewind(); } // {{{ ArrayAccess public function offsetExists($offset) { return isset($this->values[$offset]); } public function offsetGet($offset) { if (!array_key_exists($offset, $this->values)) { throw new OutOfBoundsException; } return $this->values[$offset]; } public function offsetSet($offset, $value) { // 面倒なのでイテレータは変更不可。 throw new BadMethodCallException; } public function offsetUnset($offset) { // 同様。 throw new BadMethodCallException; } // - ArrayAccess }}} // {{{ Countable public function count() { return count($this->values); } // - Countable }}} // {{{ SeekableIterator public function current() { if (!$this->next) { throw new OutOfBoundsException; } return $this->next[1]; } public function key() { if (!$this->next) { throw new OutOfBoundsException; } return $this->next[0]; } public function next() { $this->next = each($this->values); } public function rewind() { reset($this->values); $this->next(); } public function seek($position) { if (!array_key_exists($position, $this->values)) { throw new OutOfBoundsException; } $this->rewind(); while ($this->key() != $position) { $this->next(); } } public function valid() { return !!$this->next; } // - SeekableIterator }}} protected $next; protected $values; } ?>
seek は非常に適当。まあ使わないだろうし別にいいや。