Skip to content

Instantly share code, notes, and snippets.

@yuya-takeyama
Created September 19, 2010 06:13
Show Gist options
  • Save yuya-takeyama/586466 to your computer and use it in GitHub Desktop.
Save yuya-takeyama/586466 to your computer and use it in GitHub Desktop.
<?php
/**
* List_Rubyfoo
* Rubyppoi array iterator for PHP.
*
* @author Yuya Takeyama <sign.of.the.wolf.pentagram@gmail.com>
*/
class List_Rubyfoo implements Iterator, ArrayAccess, Countable
{
/**
* Array storage
*
* @var array
*/
protected $_list;
/**
* Pointer of iterator
*
* @var int
*/
protected $_pointer;
/**
* Overloaded properties definition
* property => method
*
* @var array
*/
protected static $_overloadedProps = array(
'count' => 'count',
'size' => 'count',
'length'=> 'count',
'first' => 'first',
'last' => 'last',
'max' => 'max',
'min' => 'min'
);
/**
* Method aliases
*
* @var array
*/
protected static $_aliases = array(
'collect' => 'map',
'detect' => 'find',
'find_all' => 'select'
);
/**
* Constructor
*
* @param array $list variable argument is also available.
*/
public function __construct($list = array())
{
if (is_array($list)) {
$this->_list = $list;
} else {
$this->_list = func_get_args();
}
$this->rewind();
}
/**
* Property overloading
* Properties defined in self::$_overloadProps calls method.
*
* @param string $key
* @return mixed
*/
public function __get($key)
{
if (array_key_exists($key, self::$_overloadedProps)) {
$method = self::$_overloadedProps[$key];
return $this->$method();
}
throw new Exception("Undefined property '{$key}' is called.");
}
/**
* Method aliases
*
* @param string $method name of called method
* @param array $args arguments
* @return mixed
*/
public function __call($method, $args)
{
}
public function new_($list = array())
{
if (is_array($list)) {
return new self($list);
} else {
return new self(func_get_args());
}
}
public function push()
{
foreach (func_get_args() as $v)
{
$this->_list[] = $v;
}
return $this;
}
public function pop()
{
return array_pop($this->_list);
}
public function unshift()
{
$args = array(&$this->_list);
foreach (func_get_args() as $val)
{
$args[] = $val;
}
call_user_func_array('array_unshift', $args);
return $this;
}
public function shift()
{
return array_shift($this->_list);
}
public function join($glue)
{
return join($glue, $this->_list);
}
public function first()
{
return $this->_list[0];
}
public function last()
{
return $this->_list[count($this->_list) - 1];
}
public function slice() {}
public function each($func)
{
foreach ($this->_list as $val)
{
if ($func($val) === false) {
break;
}
}
return $this;
}
public function each_with_index() {}
public function count()
{
return count($this->_list);
}
public function map($func)
{
return new self(array_map($func, $this->_list));
}
public function grep($func)
{
$result = new List_Rubyfoo;
foreach ($this->_list as $val)
{
if ($func($val)) {
$result->push($val);
}
}
return $result;
}
public function find($func)
{
foreach ($this->_list as $val)
{
if ($func($val)) {
return $val;
}
}
}
public function select($func)
{
$result = new List_Rubyfoo;
foreach ($this->_list as $val)
{
if ($func($val)) {
$result->push($val);
}
}
return $result;
}
public function reduce($func)
{
return array_reduce($this->_list, $func);
}
public function sum()
{
return $this->reduce(function ($a, $b) { return $a + $b; });
}
public function dump() {}
public function to_a()
{
return $this->_list;
}
public function all($func)
{
foreach ($this->_list as $val)
{
if (!$func($val)) {
return false;
}
}
return true;
}
public function any($func)
{
foreach ($this->_list as $val)
{
if ($func($val)) {
return true;
}
}
return false;
}
public function sort()
{
sort($this->_list);
return $this;
}
public function sort_by() {}
public function rewind()
{
$this->_pointer = 0;
}
public function current()
{
return $this->_list[$this->key()];
}
public function key()
{
return $this->_pointer;
}
public function valid() {}
public function next()
{
$this->_pointer++;
}
public function offsetGet($key)
{
if (array_key_exists($key, $this->_list)) {
return $this->_list[$key];
}
throw new OutOfBoundsException;
}
public function offsetSet($key, $val)
{
$this->_list[$key] = $val;
return $this;
}
public function offsetExists($key) {}
public function offsetUnset($key) {}
}
<?php
require_once '../test_helper.php';
require_once 'List/Rubyfoo.php';
/**
* Test class for List_Rubyfoo.
* Generated by PHPUnit on 2010-09-18 at 10:08:33.
*/
class List_RubyfooTest extends PHPUnit_Framework_TestCase
{
/**
* @var List_Rubyfoo
*/
protected $_list;
/**
* Sets up the fixture, for example, opens a network connection.
* This method is called before a test is executed.
*/
protected function setUp()
{
$this->_list = new List_Rubyfoo(1, 2, 3, 4, 5);
}
public function testNew_()
{
$expected = clone $this->_list;
$this->assertEquals($expected, $this->_list->new_(1, 2, 3, 4, 5));
}
public function testNew_static()
{
$this->assertEquals($this->_list, List_Rubyfoo::new_(1, 2, 3, 4, 5));
}
public function testPush()
{
$expected = new List_Rubyfoo(1, 2, 3, 4, 5, 6);
$this->assertEquals($expected, $this->_list->push(6), 'push() adds an element on end of list.');
}
public function testPop()
{
$this->assertEquals(5, $this->_list->pop(), 'pop() gets the last element.');
}
public function testPop2()
{
$expected = new List_Rubyfoo(1, 2, 3, 4);
$this->_list->pop();
$this->assertEquals($expected, $this->_list);
}
public function testShift()
{
$this->assertEquals(1, $this->_list->shift());
}
public function testShift_2()
{
$expected = new List_Rubyfoo(2, 3, 4, 5);
$this->_list->shift();
$this->assertEquals($expected, $this->_list);
}
public function testUnshift()
{
$expected = new List_Rubyfoo(0, 1, 2, 3, 4, 5);
$this->assertEquals($expected, $this->_list->unshift(0));
}
public function testJoin()
{
$this->assertEquals('1,2,3,4,5', $this->_list->join(','), 'join() joins each elements with glue.');
}
public function testFirst()
{
$this->assertEquals(1, $this->_list->first());
$this->assertEquals(1, $this->_list->first);
}
public function testLast()
{
$this->assertEquals(5, $this->_list->last());
$this->assertEquals(5, $this->_list->last);
}
/**
* @todo Implement testSlice().
*/
public function testSlice()
{
// Remove the following lines when you implement this test.
$this->markTestIncomplete(
'This test has not been implemented yet.'
);
}
public function testEach()
{
$result = '';
$this->_list->each(function ($n) use (&$result)
{
$result .= "{$n},";
});
$this->assertEquals('1,2,3,4,5,', $result);
}
public function testEachBreaksWhenFalseReturned()
{
$result = '';
$this->_list->each(function ($n) use (&$result)
{
if ($n > 3) {
return false;
}
$result .= "{$n},";
});
$this->assertEquals('1,2,3,', $result);
}
/**
* @todo Implement testEach_with_index().
*/
public function testEach_with_index()
{
// Remove the following lines when you implement this test.
$this->markTestIncomplete(
'This test has not been implemented yet.'
);
}
public function testCount()
{
$this->assertEquals(5, $this->_list->count());
$this->assertEquals(5, $this->_list->size);
$this->assertEquals(5, $this->_list->length);
$this->assertEquals(5, count($this->_list));
}
public function testMap()
{
$expected = new List_Rubyfoo(1, 4, 9, 16, 25);
$this->assertEquals($expected, $this->_list->map(function ($x) { return $x * $x; }));
}
public function testGrep()
{
$expected = new List_Rubyfoo(4, 5);
$this->assertEquals($expected, $this->_list->grep(function ($x) { return $x > 3; }));
}
public function testFind()
{
$this->assertEquals(2, $this->_list->find(function ($x) { return $x % 2 === 0; }));
}
public function testSelect()
{
$expected = new List_Rubyfoo(2, 4);
$this->assertEquals($expected, $this->_list->select(function ($x) { return $x % 2 === 0; }));
}
public function testReduce()
{
$this->assertEquals(15, $this->_list->reduce(function ($a, $b) { return $a + $b; }));
}
public function testSum()
{
$this->assertEquals(15, $this->_list->sum());
}
/**
* @todo Implement testDump().
*/
public function testDump()
{
// Remove the following lines when you implement this test.
$this->markTestIncomplete(
'This test has not been implemented yet.'
);
}
public function testTo_a()
{
$this->assertEquals(array(1, 2, 3, 4, 5), $this->_list->to_a());
}
public function testAll()
{
$this->assertTrue($this->_list->all(function ($x) { return $x < 6; }));
}
public function testAll_fail()
{
$this->assertFalse($this->_list->all(function ($x) { return $x < 5; }));
}
public function testAny()
{
$this->assertTrue($this->_list->any(function ($x) { return $x === 5; }));
}
public function testAny_fail()
{
$this->assertFalse($this->_list->any(function ($x) { return $x === 6; }));
}
public function testSort()
{
$unsorted = new List_Rubyfoo(5, 1, 4, 2, 3);
$this->assertEquals($this->_list, $unsorted->sort());
}
/**
* @todo Implement testSort_by().
*/
public function testSort_by()
{
// Remove the following lines when you implement this test.
$this->markTestIncomplete(
'This test has not been implemented yet.'
);
}
public function testRewind()
{
$this->_list->next();
$this->_list->rewind();
$this->assertEquals(1, $this->_list->current());
}
public function testCurrent()
{
$this->assertEquals(1, $this->_list->current());
$this->_list->next();
$this->assertEquals(2, $this->_list->current());
}
public function testKey()
{
$this->assertEquals(0, $this->_list->key());
$this->_list->next();
$this->assertEquals(1, $this->_list->key());
}
/**
* @todo Implement testValid().
*/
public function testValid()
{
// Remove the following lines when you implement this test.
$this->markTestIncomplete(
'This test has not been implemented yet.'
);
}
/**
* @todo Implement testNext().
*/
public function testNext()
{
// Remove the following lines when you implement this test.
$this->markTestIncomplete(
'This test has not been implemented yet.'
);
}
public function testOffsetGet()
{
$this->assertEquals(5, $this->_list[4]);
}
/**
* @expectedException OutOfBoundsException
*/
public function testOffsetGet_exception()
{
$this->_list[5];
}
public function testOffsetSet()
{
$expected = new List_Rubyfoo(5, 2, 3, 4, 5);
$this->_list[0] = 5;
$this->assertEquals($expected, $this->_list);
}
/**
* @todo Implement testOffsetExists().
*/
public function testOffsetExists()
{
// Remove the following lines when you implement this test.
$this->markTestIncomplete(
'This test has not been implemented yet.'
);
}
/**
* @todo Implement testOffsetUnset().
*/
public function testOffsetUnset()
{
// Remove the following lines when you implement this test.
$this->markTestIncomplete(
'This test has not been implemented yet.'
);
}
}
<?php
require_once 'PHPUnit/Framework.php';
set_include_path(get_include_path() . PATH_SEPARATOR . __DIR__ . '/../lib');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment