PHP: 2009年1月アーカイブ

Smartyのforeachは大変便利ですが、from=$list で渡した配列を全要素ループしてしまいます。

全部ではなく、例えば$listの要素のうちの5個分だけループしたいときは、"index"プロパティを使うとできました。

{foreach from=$list item=var name=myloop}
{if $smarty.foreach.myloop.index < 5 }
{$var}
{/if}
{/foreach}

PHPのOOPとJavaコードを比較してみた   はてなブックマークに登録  

前回の記事ですが、オリジナルはJavaで書かれています。
Java版とPHP版を比較してみると、コード記述にほとんど差がない。
むしろJavaの方が若干コード量が少ない気がする。
ショック!

Java版

http://www.objectclub.jp/technicaldoc/testing/stack_tdd.pdfより引用
import java.util.EmptyStackException;
/**
* @author koji,hiranabe
*/
public class Stack {

    private int[] value = new int[10];
    private int size;

    public boolean isEmpty() {
        return size == 0;
    }
    public int top() {
        emptyCheck();
        return value[size - 1];
    }
    public void push(int value) {
        this.value[size++] = value;
    }
    public int size() {
        return size;
    }
    public void pop() {
        emptyCheck();
        --size;
    }
    private void emptyCheck() {
        if (isEmpty())
        throw new EmptyStackException();
    }
}

PHP版

<?php
class Stack {

    protected $value = array();
    protected $size = 0;

    public function isEmpty() {
        return $this->size == 0;
    }
    public function top()  {
        $this->emptyCheck();
        return $this->value[$this->size - 1];
    }
    public function push($x)  {
        $this->value[$this->size ++ ] = $x;
    }
    public function size()  {
        return $this->size;
    }
    public function pop()  {
        $this->emptyCheck();
        $this->size--;
    }
    private function emptyCheck()  {
        if($this->isEmpty()){
            throw new OutOfRangeException();
        }   
    }
}
?>
Ligthweight Languageとは名ばかりの。。。
PHPのOOPはもはやLLではないのか(涙

[PHP] limeでTDDを体験する   はてなブックマークに登録  

PerlのTest::Moreに相当するものが、PHPではlime.phpというやつである。

Kwappa開発室-TDDを体験する という記事で、PHPUnitを使ってTDD体験という話が大変面白かった。
私も体験してみようと思ったが、limeしか使えないのでlimeでTDD体験をしてみた。

準備

lime.phpを入手して、WEBサーバ上の任意のディレクトリに以下のように配置する。
  • lime.php
  • Stack.class.php (空ファイル)
  • TestStack.php (空ファイル)
これから「スタック」という機能を持つクラスを作ります。
仕様はリンク先を参考のこと。

なお、私は諸事情により、コマンドラインではなくブラウザ上で実行しました。

Stack.class.php
クラスを定義する。
<?php

class Stack {

}

?>
TestStack.php
他の2つのクラスを読み込む。
<?php

require_once("lime.php");
require_once("Stack.class.php");

$stack = new Stack();
$t = new lime_test();

?>

TDDをする

まずテストをかく。
TestStack.php
<?php

require_once("lime.php");
require_once("Stack.class.php");

$stack = new Stack();
$t = new lime_test();

echo("<pre>");  // 出力を整形する

$t->diag('Stack Test');  // テストの宣言
$t->ok($stack->isEmpty(), 'isEmpty');  // これが1個目のテスト

echo("</pre>");

?>

そして、失敗するように実装をかく。
Stack.class.php
<?php

class Stack {
    public function isEmpty()
    {
        return false;
    }

}

?>

StackTest.phpを実行すると、見事に失敗する。

以下略
(リンク先のブログ記事をご参照くだされ)

最終的に書いたコード

最終的にはこのようなコードになりました。
テストコード
TestStack.php
<?php
require_once("lime.php");
require_once("Stack.class.php");
echo(1);

$stack = new Stack();
$t = new lime_test();

echo("<pre>");
$t->diag('Stack Test');

try{
    $stack->pop();
    $t->fail('Exception not thrown when void pop');
}catch(OutOfRangeException $e){
}

try{
    $stack->top();
    $t->fail('Exception not thrown when void top');
}catch(OutOfRangeException $e){
}

$t->ok($stack->isEmpty(), 'isEmpty');

$stack->push(1);
$t->ok(!$stack->isEmpty(), 'NOT isEmpty');

$t->is($stack->top(),1,'top');
$t->is($stack->size(),1,'size');
$stack->push(2);
$t->is($stack->size(),2,'size');
$t->is($stack->top(),2,'top');

$stack->push(0);
$t->is($stack->top(),0,'top');
$stack->pop();

$stack->pop();
$t->is($stack->top(),1,'top');
$stack->pop();
$t->is($stack->size(),0,'pop');

$t->ok($stack->isEmpty(), 'isEmpty');

try{
    $stack->pop();
    $t->fail('Exception not thrown when void pop');
}catch(OutOfRangeException $e){
}

try{
    $stack->top();
    $t->fail('Exception not thrown when void top');
}catch(OutOfRangeException $e){
}

echo("</pre>");

?>
テスト対象のクラスコード
Stack.class.php
<?php

class Stack {

    protected $value = array();
    protected $size = 0;

    public function isEmpty()
    {
        return $this->size == 0;
    }
    
    public function push($x)
    {
        $this->value[$this->size ++ ] = $x;
    }
    
    public function top()
    {
        $this->emptyCheck();
        return $this->value[$this->size - 1];
    }

    public function size()
    {
        //return 0;
        return $this->size;
    }
    
    public function pop()
    {
        $this->emptyCheck();
        $this->size--;
    }
    
    private function emptyCheck()
    {
        if($this->isEmpty()){
            throw new OutOfRangeException();
        }
    
    }
}

?>
テスト結果
# Stack Test
ok 1 - isEmpty
ok 2 - NOT isEmpty
ok 3 - top
ok 4 - size
ok 5 - size
ok 6 - top
ok 7 - top
ok 8 - top
ok 9 - pop
ok 10 - isEmpty
1..10
 Looks like everything went fine.

ほ~勉強になった。
やっぱ体験は重要ですな。

プチ楽しかったです。
みなさんもぜひ。

このアーカイブについて

このページには、2009年1月以降に書かれたブログ記事のうちPHPカテゴリに属しているものが含まれています。

前のアーカイブはPHP: 2008年12月です。

次のアーカイブはPHP: 2009年6月です。