#48277 [NEW]: need a way to do type safe enumerations in php

2009-05-14 Thread nairbv at yahoo dot com
From: nairbv at yahoo dot com
Operating system: 
PHP version:  6CVS-2009-05-14 (CVS)
PHP Bug Type: Feature/Change Request
Bug description:  need a way to do type safe enumerations in php

Description:

**This is a feature request, not a bug

I can find no reasonable way of implementing any kind of useful typesafe
enumeration pattern in php without an additional language feature.  There
are a number of potential language features that could fix this.  Here are
a couple of examples.

1) a final keyword for static class members, and permitting static
initialisation at class load time.  Final is *not* the same thing as
const.  final + load-time initialisers would allow code like this:

final class color {
private $name;
public static final $RED = new boolean('Red');
public static final $ORANGE = new boolean('Orange');
//.
function __construct($name){ $this-name=$name; }
function __toString() { return $this-name; }
}

without static, you can't initialise them in the class.  Without final,
any user of your class can color::RED = color::ORANGE (maybe accidentally
in an if statement) and you're class is hosed.  With const, they can only
be primitives, which can't have any functionality or attributes.  Finals
would be initialised at run time (sometimes even in constructors etc, as
long as they are only initialised once).

Don't confuse what I said about static initialisers with late static
binding, an already planned feature un-related to this request.

2) or, including an actual enum class would be nice.  see:
http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html for an
example.

3) ideally we'd have both.  Having an enum class is obviously better than
my first suggestion for the specific problem of implementing enums, but the
features in my first suggestion also have other applications.

I'm seeing a lot of code that in various ways attempts to work around this
lack.  None of them are elegant, in that they all involve repetitive, hard
to read, or unsafe code.

one example I came across recently looked like this:
final class foo {
static $foo;
static $bar;

function __construct()
{
$foo = new someotherclass('attribute1','attribute2');
$bar = new someotherclass('attribute3','attribute4');
}
}
new foo();

there was a comment before new foo(); in this code (written by someone
else) that said:

need to instantiate class to fill static members. I don't like this
setup, but haven't found a better way yet to have const members of class or
interface be instantiated objects rather than constant expressions.

It happens frequently enough.  In this code that I found, an accidental
assignment in an if statement breaks other calling code due to lack of
final.  Lack of load-time static initialisation means that class members
have to be instantiated by a call outside the class definition, and that
every member (the real class has about 100 members) has to be defined
twice.

I've also seen code like:

final class my_things {
private $name;
private static $all_things = array();
function __construct($name,$otherstuff) {
$this-name=$name;

self::$all_things[$name] = $this;
}
static function get_by_name($name) { 
return self::$all_things[$name]; 
}
}

new my_things('thing1',...);
new my_things('thing2',...);


which, is also far less than ideal... and doesn't maintain any usable
reference to the actual enumeration.  Each one must be looked up by it's
reference string, often defined elsewhere as a series of consts.  It can
also be added to since the constructor must be public.

The closest you can come to getting a real enum in php is to use public
static final functions to get the enumerated values.  This requires a lot
of plumbing code, i.e., a factory method that caches values so new ones are
not constructed on every call (because we want to boolean::TRUE() ===
boolean::TRUE() not just ==, etc), and an entire function definition in
which each enumerated value is instantiated/returned.

The late static binding feature being added in 5.3 might enable someone to
write an enum superclass (function based) getting around *some* of this
plumbing code, but using functions as enumerations would still be an ugly
hack.

There are so many places where this is useful.  Say I want to add a list
of log levels to a logging class.  I want each log level to be a numeric
value that can be compared, and have a string representation that can be
printed.  It can't be done in any safe, non-repetitive, object oriented,
clean way.



Reproduce code:
---
n/a

Expected result:

n/a

Actual result:
--
n/a

-- 
Edit bug report at http://bugs.php.net/?id=48277edit=1
-- 
Try a CVS snapshot (PHP 5.2):
http://bugs.php.net/fix.php?id=48277r=trysnapshot52
Try a CVS snapshot (PHP 5.3):
http://bugs.php.net/fix.php?id=48277r=trysnapshot53
Try a CVS

#47783 [NEW]: Error messages often don't make sense.

2009-03-25 Thread nairbv at yahoo dot com
From: nairbv at yahoo dot com
Operating system: 
PHP version:  5.2.9
PHP Bug Type: Feature/Change Request
Bug description:  Error messages often don't make sense.

Description:

Error messages often don't make sense.  for example:

Catchable fatal error:  Argument 1 passed to my_function() must be an
instance of string, string given

I'd comment on this bug:
http://bugs.php.net/bug.php?id=42118

But this reporting system doesn't permit commenting on existing bugs.

The bug is NOT bogus.  The error message IS non-sense.  It's fine if
you're not going to support primitive type hinting, but the message should
say something to that effect.

Also the error is NOT catchable.  See bug:
http://bugs.php.net/bug.php?id=41948

Again, I'd comment on that bug, but I can't comment on existing bugs.

If the error can only be handled by setting an error handler, and not
caught with a catch block, the error message should say RECOVERABLE
error or handleable or something to that effect, not catchable error.

Other bad error messages include:
Can't use method return value in write context
see bug: http://bugs.php.net/bug.php?id=44565

write context is meaningless to the programmer.

On that bug, the reporter commented that the message is not helpful.  Why
was the bug closed instead of fixing the error message??



Reproduce code:
---
for the first error message:
function my_function(string $str) {}
bar('');

for the second error message:
empty($foo-getValue());

or also the code in bug #44565.



Expected result:

error messages that help the programmer.  

for the catchable error regarding type hinting:
Either something like: 
Recoverable fatal error: reference to undefined class 'string' on line
[line of type hint] or:
Recoverable fatal error:  Argument 1 passed to my_function() must be an
instance of class string, primitive string given.

For the empty($foo-getbar());write context message:
It should probably say something like cannot use method return value when
calling internal language constructs ... or something like that.

For the write context message referenced in bug 44565:
it should give the 'call-time pass-by-reference is deprecated when you
use  in foo($a);' like the documentation
(http://docs.php.net/manual/en/language.references.pass.php) says it will.


Actual result:
--
Useless (and sometimes amusing) error messages like must be an instance
of string, string given or the write context message which as far as I
know is in reference to some implementation detail internal to php.


-- 
Edit bug report at http://bugs.php.net/?id=47783edit=1
-- 
Try a CVS snapshot (PHP 5.2):
http://bugs.php.net/fix.php?id=47783r=trysnapshot52
Try a CVS snapshot (PHP 5.3):
http://bugs.php.net/fix.php?id=47783r=trysnapshot53
Try a CVS snapshot (PHP 6.0):
http://bugs.php.net/fix.php?id=47783r=trysnapshot60
Fixed in CVS:
http://bugs.php.net/fix.php?id=47783r=fixedcvs
Fixed in CVS and need be documented: 
http://bugs.php.net/fix.php?id=47783r=needdocs
Fixed in release:
http://bugs.php.net/fix.php?id=47783r=alreadyfixed
Need backtrace:  
http://bugs.php.net/fix.php?id=47783r=needtrace
Need Reproduce Script:   
http://bugs.php.net/fix.php?id=47783r=needscript
Try newer version:   
http://bugs.php.net/fix.php?id=47783r=oldversion
Not developer issue: 
http://bugs.php.net/fix.php?id=47783r=support
Expected behavior:   
http://bugs.php.net/fix.php?id=47783r=notwrong
Not enough info: 
http://bugs.php.net/fix.php?id=47783r=notenoughinfo
Submitted twice: 
http://bugs.php.net/fix.php?id=47783r=submittedtwice
register_globals:
http://bugs.php.net/fix.php?id=47783r=globals
PHP 4 support discontinued:  http://bugs.php.net/fix.php?id=47783r=php4
Daylight Savings:http://bugs.php.net/fix.php?id=47783r=dst
IIS Stability:   
http://bugs.php.net/fix.php?id=47783r=isapi
Install GNU Sed: 
http://bugs.php.net/fix.php?id=47783r=gnused
Floating point limitations:  
http://bugs.php.net/fix.php?id=47783r=float
No Zend Extensions:  
http://bugs.php.net/fix.php?id=47783r=nozend
MySQL Configuration Error:   
http://bugs.php.net/fix.php?id=47783r=mysqlcfg