How do you feel about type-hinting

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: How do you feel about type-hinting

Post by VladSun »

Jenk wrote:... I just don't get why people have to know everything before they have even tried running it.
:twisted:

Code: Select all

#: rm -rf /
There are 10 types of people in this world, those who understand binary and those who don't
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Re: How do you feel about type-hinting

Post by Jenk »

VladSun wrote:
Jenk wrote:... I just don't get why people have to know everything before they have even tried running it.
:twisted:

Code: Select all

#: rm -rf /

Code: Select all

# rm -rfi /
:p
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: How do you feel about type-hinting

Post by alex.barylski »

Or you could just run the app, and see which members are missing by information from the error message. I just don't get why people have to know everything before they have even tried running it.
Because, some people are of the school of thought, where failing to plan is planning to fail? :P

Seriously though, I hate surprises and unexpected side effects, I am very meticulous by nature, having docs before I go experimenting would be of great help, although I don't know if I would care for tye hinting in this regard, maybe when dealing with a framework where objects are being used and passed around. At the application level though, say when dealing with a model, chances are 90% of the parameters are scalars and the variable name itself should probably imply 'type':

Code: Select all

function createPerson($first_name, $last_name, $age)
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Re: How do you feel about type-hinting

Post by Jenk »

your tests would catch the error long before you deploy.
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: How do you feel about type-hinting

Post by alex.barylski »

your tests would catch the error long before you deploy.
What error are you talking about?
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: How do you feel about type-hinting

Post by alex.barylski »

It should be noted, that I am not advocating either a explicit parameter list, or associative arrays.

I just think, there has to a better solution to address the issues (advantages or disadvantages) both have.
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Re: How do you feel about type-hinting

Post by Jenk »

PCSpectra wrote:
your tests would catch the error long before you deploy.
What error are you talking about?
The one I spoke of that you quoted. :) I.e. member missing.
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: How do you feel about type-hinting

Post by alex.barylski »

It's been a while, but I don't recall my test catching this error, and I'm not sure you understood what I was getting at:

I had two identical objects, so assume something like:

Code: Select all

 
abstract class A{
  function getValue(){ return $this->value; }
}
 
class B extends A {}
 
class C extends A {}
Now in my caller code I did something like this:

Code: Select all

 
some_method($a, $b)
{
  $t = $a->getValue('test');
}
 
some_method(new B(), new C()); // See the error?
 
Objects A and B are identical but 'type' matters (incase your curious they were a registry and a request object) as 'A' was the request, not a registry object, when I called on getValue() in some_method() I did not receive the expect value and it was a bug that caught me with my pants off for a lot longer than I wish to have spent.

Had I used type-hinting in the argument list, the interpreter would have caught the error, and notified me.

Testing the some_method() did little (from what I remember) because both request and response were probably mocked and returned what I told them to in the setup.

Running the code in realtime however, would have produced buggy code, as the request object was actually of type registry and had only the variables I pushed into that object at bootstrap, not the POST'ed data I was expecting.

I fail to see how a test would help catch this error I spoke of...would you not have to 'test' (no pun intended) for the type explicitly in the test itself?

I don't see any other way to disambiguate the two objects in this case except in using 'type'. Perhaps if some_method() (which was a action controller I believe) pulled on a method other than the identical getValue() a unit test would caught me with my pants down and I would have saved time (but the interpreter would do the same thing letting me know an illegal method was called on object).

Edge case? I think so :)

Cheers,
Alex
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Re: How do you feel about type-hinting

Post by Jenk »

Integration test would have caught that. I realise it's an example, but I'd also question the design of an objects interface if one of the arguments is ignored. :)
WaffleSouffle
Forum Newbie
Posts: 1
Joined: Thu May 07, 2009 7:16 am

Re: How do you feel about type-hinting

Post by WaffleSouffle »

I'm posting here because it seems on-topic, and it's a concrete example of when type hinting has got in the way.

I've been trying to use SimpleTest. It mocks things which is great, but frankly mocking mysqli objects is a pain.
For example, using the simple test mock generator you get a sub-class of the mysqli/MySQLi_STMT/mysqli_result classes, except you can't set any predefined properties such as "insert_id" on any instances, and possibly other problems I haven't run into yet.

Since these properties are essentially a part of the interface, they're going to be used in code, and therefore mock objects have to support them.

In an attempt to work around that, there are posts recommending generating a class derived from stdClass which has all the methods of the built-in required (see http://osdir.com/ml/php.simpletest.gene ... 00057.html). I've been using this approach, and it works OK. I have clumsy but mockable database objects.

Now our database code has been altered to support type hints.

Mock objects which "look like but aren't actually" the classes they mock won't do. On the other hand the reason I reached for this solution was because mocking the internal PHP classes wasn't working well enough, and even if it did I think it's perfectly valid to want to pass a different class. Type hinting interfaces would be fine in this situation.

I'm left with considering nasty hacks, like different wrappers around the real database code. One set of wrappers for when testing (i.e. no type hints), the other when not testing. Bleh.

An alternative that PHP doesn't support is function overloading in the traditional, not magic methods prefixed with __, sense. If I could overload my functions with different type hints, I might have an escape route, although I think it would still lead to code duplication and wrapper functions galore.

How do I feel about type-hinting ? All built-in classes should implement interfaces. I might even go so far as to say type hints should support interfaces, and not classes.
User avatar
m4rw3r
Forum Commoner
Posts: 33
Joined: Mon Aug 03, 2009 4:19 pm
Location: Sweden

Re: How do you feel about type-hinting

Post by m4rw3r »

I like type-hinting, but I think it should be moderated. I mean, don't use it everywhere, just where it makes sense (like when an object with a certain interface is required).

And about those unit tests, what I've done as a fix for the problem of final classes which needs to be mocked is this (Using PHPUnit):

1. Use an autoloader for the classes to test, so I don't load the class to test until it is needed (or you can load them in the tests themselves)
2. Create the test which requires a mock of the final class, and use the @runInSeparateProcess annotation (makes PHPUnit reload PHP for that test, cleaning all loaded classes)
3. Use eval() to create a mock class with the same name (or just use $this->getMock() directly, if it doesn't require any special logic)

This will obviously not work with built-in classes as they are already loaded, but I cannot remember any built-in class which is declared final.
Post Reply