tags:

views:

77

answers:

5

For example lets say I have a set of classes and methods to do so:

$obj->method1()->method2();

Is there anyway for method1() to know with in itself that its the first method being called or for method2 to know that its the last?

Some more details
I just want to be able to build a set of these calls so that it either returns an instance of itself if the call to the method isnt at the end of the chain or return something different if its at the end.

For example

$obj->method1()->method2(); #Here method 2 will return lets say a string.
$obj->method1()->method2()->method3(); #Since method2 isnt at the end of the chain, it should return an instance of itself (or another object) here so that the chain could continue.

EDIT: anyone whoz trying to do this - it is a bad design pattern.

This does seem to be a duplicate. Refer to this question for more answers.

A: 

I don't think this is possible, no -- at least, I've never seen anything about this.

(Out of curiosity : why would you need that ? Maybe it would be possible to use onther solution to solve your actual problem ?)

Pascal MARTIN
+1  A: 

Not out of the box, not even with a Stack trace.

I guess you could put something together using constants or global variables:

Don't try this at home!

$GLOBALS["chain"] = array();
$obj->method1()->method2();    // method1 adds member to $GLOBALS["chain"], 
                               // array_push($GLOBALS["chain"], __FUNCTION__);
                               // method2 does the same...
print_r($GLOBALS["chain"]);

That would give you the full chain - not yet which one is the last one, to do that, you would have to pass a flag to method2().

But it would be horribly hacky and pollute your code.

Is there a specific reason you need this for?

Pekka
+1 "Don't try this at home!" :),But actually you can add a private array/map for that!.
Omar Dolaimy
A: 

The only way this is possible is to let the methods save some global state.

If both methods are in the same class, you could add a variable to the class and let each class set a unique value.

But the question is if this is desirable. This kind of behavior is often not very smart in the long run.

Ikke
A: 

Seriously? Consider the possibilities. How do we make things do one thing for one instance and another for another? True/false? Just have each method return the instance of itself if false or the other object if true, then add your true parameter for the last method in each chain. There is no need to go off creating fancy codes that will take up way more space than your simple on/off switch.

animuson
A: 

All you could do is find out which methods have been called so far, by setting some kind of global state in the class. But you can't find out what methods are being called after a method, and you wouldn't be able to tell the difference between methods in one chain and methods in another:

$obj->m1()->m2();
$obj->m3(); // You would think that m1() and m2() came before this in the same chain

You would need to have a method at the end of each chain to clear the global state in the class.

Since it seems you need to see which method comes next in a chain, this won't work for you.

I would say that this is a really bad design pattern, at least for PHP (and every other language I've worked in). Each method should do one thing only. If you need a method to either return a string or an object depending on what you need it for later, you are doing something wrong.

Granted, I have done something like this before. It was a meta-information class for images submitted by users -- you could set it up like this:

$meta = new ImageMeta();
$meta->first_name("foo")->last_name("bar")->email("baz")->id("guid");

But, if you did this:

$meta->first_name();

it would return a string. The default value for the first parameter was NULL, and if the method got NULL, it returned a string. Otherwise it set (and escaped) an internal value and returned $this.

At first I thought it was kind of cool, but it turned out to be a mistake. I hate using that class now. Just make one method/function do one thing only and you will be much happier.

Carson Myers