xp-framework/rfc — Issue #10: Type casts
Author: thekid
Created: 2011-10-17 15:26:36+00:00
State: closed
Labels: framework, implemented

Scope of Change
====
The core function cast() is changed to support class hierarchies
correctly. Also, cast() should no longer change the passed variable.

Rationale
====
The current model allows users to cast between arbitrary types.

Functionality
====

Motivation
----
Consider the following sourcecode:

```php
getValue('user');
echo $user->getUsername();
?>
```

Because HttpSession::getValue() returns anything, we cannot be really sure
that we get a user object, or an object at all; in both cases we'd see a
fatal error occuring.

We could now rewrite the code to:

```php
getValue('user');
if (!$user instanceof User) {
throw new IllegalStateException('Session key "user" is not a User instance');
}
echo $user->getUsername();
?>
```

This RFC suggests to rewrite that to the following:

```php
getValue('user'), 'com.example.vo.User');
echo $user->getUsername();
?>
```

The cast function would raise an exception in case the value returned is
not a User instance, thus yielding the same behaviour as the second
example.

Syntax
----

```
T cast(Generic expression= NULL, TypeRef::T class)

```

Null values
----
Null values are casted to xp::null().

```php
putValue('user', NULL);
$user= cast($session->getValue('user'), 'com.example.vo.User');
echo $user->getUsername(); // *** NullPointerException ***
?>
```

Primitives
----
Primitives can not be cast. An IllegalArgumentException will be raised
if a primitive is passed as value.

Objects
----
An object can be cast to:
* Its own class
* One of its superclasses
* One of its interfaces

```php

```

If the destination class does not exist, a lang.ClassNotFoundException
will be thrown.

```php

```

Dependencies
====
New class:
* lang.ClassCastException
Thrown to indicate hierarchy errors (see above for example)

Related documents
====
- http://de3.php.net/manual/en/language.types.type-juggling.php
PHP Manual: Type Juggling

- http://xp-framework.net/rfc/contrib/rfc0010.diff
Implementing patch and unittest