WEBアプリケーション研究室 開発ノート TOP

WEBアプリケーション研究室 開発ノート 2010年02月

スポンサーサイト

-------- --:--

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

    このエントリーをはてなブックマークに追加

teeというコマンドがあります。
標準・エラーともに出力するならこんな感じでしょうか。


command 2>&1 | tee file.txt

    このエントリーをはてなブックマークに追加

linuxでフォルダの合計容量を調べるコマンドです。


du -s
du -sh(単位を見やすく)

    このエントリーをはてなブックマークに追加

オブジェクトにforeachができるようにするIteratorと、配列のようにアクセスできるArrayAccessというインターフェスがありますが、同時に付けてunsetを使用すると思わぬ動きになります。


class MyList implements Iterator, ArrayAccess {
private $position = 0;
private $array;

public function __construct() {
$this->position = 0;
}

public function isEmpty() {
return empty($this->array);
}

//ArrayAccess
public function offsetSet($offset, $value)
{
$this->array[$offset] = $value;
}

public function offsetExists($offset)
{
return isset($this->array[$offset]);
}

public function offsetUnset($offset)
{
unset($this->array[$offset]);
}

public function offsetGet($offset)
{
return $this->array[$offset];
}

//Iterator
public function rewind() {
$this->position = 0;
}

public function current() {
return $this->array[$this->position];
}

public function key() {
return $this->position;
}

public function next() {
++$this->position;
}

public function valid() {
return isset($this->array[$this->position]);
}
}
で、次のようなテストをします

public function testList()
{
$list1 = new MyList(array('0','1','2'));
$list2 = new MyList(array('0','1','2','3'));

foreach($list1 as $outer_key=>$item1)
{
foreach($list2 as $inner_key=>$item2)
{
if($item1 == $item2)
{
unset($list1[$outer_key]);
unset($list2[$inner_key]);
}
}
}

$this->assertTrue($list1->isEmpty());
$this->assertEquals(1, count($list2));
foreach($list2 as $value)
{
$this->assertEquals(3, $value);
}
}
このテストはこけます。ちなみん、普通の配列を使えば通るテストです。詳細に変数を追っていけば、簡単にわかるのですが、問題は、foreachで回してる配列とunsetする配列が同じところです。foreachの説明をみると、「配列が リファレンス でない限り、foreachは、指定した配列自体に対してではなく、 そのコピーに対して処理を行います。」とありますが、同じようにコピーしてやらないとこのようなコードでは問題が起きてしまいます。コピーを自分で実装することもできますが、IteratorAggregateというインターフェイスを使うと簡単です。

class MyList implements IteratorAggregate, ArrayAccess {
private $position = 0;
private $array;

public function __construct() {
$this->position = 0;
}

//ArrayAccess
public function offsetSet($offset, $value)
{
$this->array[$offset] = $value;
}

public function offsetExists($offset)
{
return isset($this->array[$offset]);
}

public function offsetUnset($offset)
{
unset($this->array[$offset]);
}

public function offsetGet($offset)
{
return $this->array[$offset];
}

//IteratorAggregate
public function getIterator()
{
return new ArrayIterator($this->array);
}
}
これだけで、さっきのテストをパスします。

    このエントリーをはてなブックマークに追加
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。