Last active
December 19, 2015 02:49
-
-
Save TorbenKoehn/5885677 to your computer and use it in GitHub Desktop.
PHP Autoboxing: What it could look like I don't think, multiple autoboxing-functions make sense, a __autobox would indeed be more useful than spl_autobox_register, since you can't "merge" multiple classes defined on autoboxes and frameworks require specific functions.
The best way would be enabling/disabling the autoboxing in frameworks, set it …
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class Type { | |
protected $value; | |
public function __construct( $value ) { $this->value = $value; } | |
abstract public function __cast( /* (string) Class name */ $type ); | |
} | |
class String extends Type { | |
public function toUppercase() { | |
$this->value = strtoupper( $this->value ); | |
return $this; | |
} | |
public function toLowercase() { | |
$this->value = strtolower( $this->value ); | |
return $this; | |
} | |
public function toArray() { | |
for( $i = 0; $i < strlen( $this->value ); $i++ ) | |
yield $this->value[ $i ]; | |
} | |
public function __cast( $type ) { | |
switch( $type ) { | |
case 'Integer': | |
return intval( $this->value ); | |
case 'Array': | |
return $this->toArray(); | |
} | |
} | |
} | |
class Integer extends Type { | |
public function add( $int ) { $this->value += $int; return $this; } | |
public function sub( $int ) { $this->value -= $int; return $this; } | |
public function div( $int ) { $this->value /= $int; return $this; } | |
public function mul( $int ) { $this->value *= $int; return $this; } | |
public function rangeFrom( $int ) { | |
for( $i = $int; $i < $this->value; $i++ ) | |
yield $i; | |
} | |
public function rangeTo( $int ) { | |
for( $i = $this->value; $i < $int; $i++ ) | |
yield $i; | |
} | |
public function __cast( $type ) { | |
switch( $type ) { | |
case 'String': | |
return strval( $this->value ); | |
case 'Array': | |
return $this->rangeFrom( 0 ); | |
} | |
} | |
} | |
class Array { | |
public function forEach( $callback ) { | |
foreach( $this->value as $k => $val ) { | |
$result = call_user_func( $callback, $val, $k ); | |
if( !is_null( $result ) ) | |
$this->value[ $k ] = $result; | |
} | |
return $this; | |
} | |
public function __cast( $type ) { | |
switch( $type ) { | |
case 'String': | |
$str = ''; | |
$this->forEach( function( $v ) use( $str ) { $str .= $v } ); | |
return $str; | |
case 'Integer': | |
throw new Exception( "Invalid cast from array to integer (how shud i do eet?)" ); | |
} | |
} | |
} | |
/* Autoboxing initialization */ | |
if( function_exists( '__autobox' ) ) | |
throw new Exception( "Sorry, autoboxing can only be used ONCE per project. " | |
. "Anything else would make no sense, other than with __autoload" ); | |
function __autobox( $primitiveType, $value ) { | |
switch( $primitiveType ) { | |
case 'string': | |
return new String( $value ); | |
case 'int': | |
return new Integer( $value ); | |
case 'array': | |
return new Array( $value ); | |
} | |
} | |
/* Possibilities */ | |
$str = 'my string'; | |
var_dump( $str->toUppercase() ); //str.value = 'MY STRING' | |
var_dump( $str->toLowercase()->toUppercase() ); //str.value = 'MY STRING' | |
$int = 14; | |
var_dump( $int->mul( 2 ) ); //int.value = 28 | |
var_dump( $int->rangeFrom( 5 ) ); //(Array)[5,6,7,...,27,28] | |
$arr = [ 0, 1, 2, 3, 4, 5 ]; | |
$arr->forEach( function( $i ) { | |
echo $i; | |
//!! return value could re-map the values easily | |
return $i * $i; | |
} ); | |
var_dump( $arr ); //arr.value = [0,2,4,9,16,25] | |
/* Type casting */ | |
$str = 'test'; | |
$arr = (Array)$str; | |
var_dump( $arr ); //arr.value = ['t','e','s','t'] | |
$int = 5; | |
$str = (String)$int; | |
var_dump( $int ); //int.value = '5' | |
$arr = (Array)$int; | |
var_dump( $arr ); //arr.value = [0,1,2,3,4,5] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* This is what __autobox with namespaces could look like */ | |
namespace MyNs; | |
//this would count for \MyNs and \MyNs\*, all subnamespaces | |
function __autobox( $primitiveType, $value ) { | |
//... | |
} | |
namespace MyNs\SomeSubNs; | |
//this would overwrite __autobox of \MyNs, but only for \MyNs\SomeSubNs and \MyNs\SomeSubNs\* | |
function __autobox( $primitiveType, $value ) { | |
//... | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment