Hello all,
I've drafted an RFC and functional-complete patch for disucssion
another alternative to add scalar object casting magic methods.
https://wiki.php.net/rfc/object_cast_to_types
Please review the RFC and attached patch, and start some discussion on
this proposal.
Thanks,
Anthony
Hi!
I've drafted an RFC and functional-complete patch for disucssion
another alternative to add scalar object casting magic methods.https://wiki.php.net/rfc/object_cast_to_types
Please review the RFC and attached patch, and start some discussion on
this proposal.
Some notes:
-
Use cases for this are unclear. Wrapping scalar types does not seem
very efficient as conversion is always one-directional - once you do any
operation your type is gone, so unless you re-wrap it each time (at
which point you could as well un-wrap it manually) it's not very useful.
Enabling passing SplFixedArray to array functions is very simple - as
with any iterable type - just use iterator_to_array (if you don't have
builtin convertor, which SplFixedArray does). But it's not always a good
idea - since it creates a full copy. Both this method and your
conversion do not have a context so it is not possible to avoid creating
a full copy. -
Having separate methods is probably not the best idea. It may lead to
implementation having inconsistent conversions between types, such as
floats and integers, etc. or having conversions to float but not int and
getting very hard to debug errors because of that. Also may lead to
conversion be context-dependent and create very confusing results. -
There's already cast_object handler, why not use it? I'm not sure
messing with get is a good idea, it's not exactly meant for that.
--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
Stas,
Some notes:
- Use cases for this are unclear. Wrapping scalar types does not seem very
efficient as conversion is always one-directional - once you do any
operation your type is gone, so unless you re-wrap it each time (at which
point you could as well un-wrap it manually) it's not very useful.
Enabling passing SplFixedArray to array functions is very simple - as with
any iterable type - just use iterator_to_array (if you don't have builtin
convertor, which SplFixedArray does). But it's not always a good idea -
since it creates a full copy. Both this method and your conversion do not
have a context so it is not possible to avoid creating a full copy.
That's quite fair and understandable. And something I'm hoping people
on the list here will be able to help out with. I know this is an
often requested feature (and I've hit cases where "it would be nice
if"). I just can't think of any good ones now.
One thing to note is that this becomes much more useful if implemented
along-side the other RFC I proposed with parameter casting (
https://wiki.php.net/rfc/parameter_type_casting_hints ).
Another thing to consider (or, let me propose), is that consistency is
a reason to add this. Right now, we can cast to string types and
control the cast, but we can't to any other type. So this would open
the ability for consistent casting across all scalar (non-object)
types...
- Having separate methods is probably not the best idea. It may lead to
implementation having inconsistent conversions between types, such as floats
and integers, etc. or having conversions to float but not int and getting
very hard to debug errors because of that. Also may lead to conversion be
context-dependent and create very confusing results.
Well, as you know that was part of my original proposal (
https://wiki.php.net/rfc/object_cast_magic ). However, after talking
with a few core devs about it, it seemed that separate methods are the
preferred solution, as the single method requires a big switch (which
isn't as clean, and will promote returning improper types, Floats when
an int was asked for, etc)... For that reason, it seems more fragile
to maintain, so I agreed with splitting it to multiple methods.
But either way, if people feel strongly, I would be willing to change
the implementation...
- There's already cast_object handler, why not use it? I'm not sure messing
with get is a good idea, it's not exactly meant for that.
cast_object goes to zend_cast_object_tostring(), which is specifically
hard-coded to return specific values for types. So rather than edit
that, I implemented a wrapper on-top to implement these additions.
That way, the current (BC) functionality remains untouched... But I
could see pushing this code into that handler. My only concern there
is naming (it's called tostring, but it does far more than that)...
As far as the get() handler, I can see the uses, but if it's really
that big of an issue (not saying you're making it out to be), I think
we can remove that part of the proposal without substantially
affecting the concept of the patch and RFC...
Thanks for the comments
Anthony
Hi!
Well, as you know that was part of my original proposal (
https://wiki.php.net/rfc/object_cast_magic ). However, after talking
with a few core devs about it, it seemed that separate methods are the
preferred solution, as the single method requires a big switch (which
isn't as clean, and will promote returning improper types, Floats when
an int was asked for, etc)... For that reason, it seems more fragile
to maintain, so I agreed with splitting it to multiple methods.
You mean the code implementing it would have switch? So what? It's not
like using switch operator is banned in PHP world. I'm not sure also how
it promotes returning float when int is requested - of course, you can
have buggy code, so you can have it when you do it with separate
methods. But having to implement 5 methods (you forgot booleans btw,
which are used by the engine - another sign why it may not be a good
idea to split) and keep them consistent may be a problem. Use cases
however should drive it, so depending on this let's see which is better.
cast_object goes to zend_cast_object_tostring(), which is specifically
hard-coded to return specific values for types. So rather than edit
case_object is used throughout the engine for various types. For PHP
user objects it can do only strings now, but this is exactly what you
wanted to change, isn't it?
that, I implemented a wrapper on-top to implement these additions.
That way, the current (BC) functionality remains untouched... But I
Which functionality do you mean? I didn't mean for you just throw out
string casting code, add to it. We have method specially created for
casting objects to scalars, why work around it instead of using it?
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
Anthony Ferrara wrote:
- Having separate methods is probably not the best idea. It may lead to
implementation having inconsistent conversions between types, such as floats
and integers, etc. or having conversions to float but not int and getting
very hard to debug errors because of that. Also may lead to conversion be
context-dependent and create very confusing results.Well, as you know that was part of my original proposal (
https://wiki.php.net/rfc/object_cast_magic ). However, after talking
with a few core devs about it, it seemed that separate methods are the
preferred solution, as the single method requires a big switch (which
isn't as clean, and will promote returning improper types, Floats when
an int was asked for, etc)... For that reason, it seems more fragile
to maintain, so I agreed with splitting it to multiple methods.
I definitely agree, separate methods are much easier to deal with and
should be the way to go here. If you use a single method for all the
casts, you'll probably end up recreating separate methods anyway (i.e.
case 'int': return $this->toInt();
) which seems silly to me.
--
Ryan McCue
<http://ryanmccue.info/