Should we support method chaining in most framework classes

Method chaining, aka. fluent interface, can be found in some places in Yii, such as the new query builder, where one can chain several method calls together, like the following:




Yii::app()->db->createCommand()

 	->select('id, title')

 	->from('tbl_post')

 	->queryAll();



We recently made the following change, trying to extend the support for method chaining to most core Yii classes:

http://code.google.c…e/detail?r=2999

However, we are not very sure if this is appropriate. There are some discussions about this changeset in the above URL.

Please cast your vote to the above poll and let us know what your thought about this change.

We will consider reverting the change if we see sufficient objection.

Thank you.

I agree where the return of the object (aka chaining) makes sense I will let it limited. The rest I am not very sure and I agree with most of your concerns.

I voted no, but I’d be better vote “don’t care”.

I don’t like by principle method chaining, it result in a bad indentation and I consider it awful.

As we are not paying typed words in kilograms, I prefer to do a bit of copy paste and write all calls separately.

Therefore it changes me nothing if there is or not the possibility of method chaining, in any case I wont use it.

I voted no because I quote the objection of qiang about the risk of inconsistency.

I’m not 100% sure it’s a good thing. Pros:

Noone forces to use method chaining and everything stays backwards compatible as it was before. If you see that method chaining makes sense you’ll use it if not, just don’t use it.

From my point of view considering to return $this or not is relatively simple. We should return $this if:

— Method doesn’t return anything else.

— Method is not the final step in object’s lifecycle. Such method is, for example, CApplication::end().

Cons:

It does not feel absolutely right but I can’t find any.

Antonio Ramirez

Any specific classes where you are missing chaining?

I wonder what will happen with method chaining, if there’s a setter e.g. setSomething($val) which returns $this:


$x = $component->something = 'bla';

What will be in $x, if the setter returns $component itself?

Besides unclear cases like this, I think i agree with Qiangs concerns:

It would look like Yii encourages the use of method chaining. It might have no impact at all, but things often develop some self-perpetuating dynamics and suddenly everyone is chaining like crazy. Which then again could have side effects like hindering the implementation of some specific new features, that would break chaining (and thus break BC).

All has been written already… I too think that chaining should be limited…

if we just add it everywhere… it can in the end bring to inconsistency as some methods return a "custom" value and some would return $this… this way users/programmers would need to check the documentation even more than now (to see what is the method returning)

I’m not objectionable to method chaining but do agree it needs to be used where it makes calls to that code easier to read. Like with the new command builder because all the calls are related to one another. Where two consecutive calls are made but are unrelated then method chaining doesn’t make sense.

I’ve always wondered however what the result of excessive method chaining does to the stack?

By checking the changes made: http://code.google.com/p/yii/source/detail?r=2999 I particularly don’t. I am more concern about the last post of Mike and what qiang says.

Nevertheless, by exposing:

I do not see much of a problem…

Stack should not be different, because every method returns, before the next one gets called.

The idea that there is more than one way to ‘do it right’ arouses my attention, as — just like practice shows — it makes simple things complicated. Because, as you add such a feature in each and every “void” & “not-final” method, immediately someone would try to benefit from it, and, still there will be those who won’t bother. Such diversity frightens already. More parties — more tension.

Not to say that, there is a hypothetical chance for those, who’ll follow the chaining way, to break their legs trying to make a chain, paying each and every attention to consider whether this or that method is chainable.

So my phobic vote is ‘No’, for chaining approach should be introduced wisely, in a limited fashion %)

I’d say that adding method chaining to every component is too much. Not only it will put more strain on developers to code new components in such way, but all extensions should then follow that method to - and that obviously will not be done in most cases, so we will have some nightmare code like




$ext = $this->component->setSomething('bla', 'test')->doSomething()->getExtensionComponent();

$ext->doThis();

$ext->doThat();

$ext->getStanardComponent()->a()->b()->c();



Na-h, don’t wana that. KISS is our best fiend, so keep it simple! :)

Using such a wide parameters for apply method chaning can result in a big block for further development.

All methods that now return nothing are ‘opened’ to further devolopment: is always possible to add a return value in future.

If it would return $this, returning anything else would result in breaking BC.

And what about methods that reutrn something now? What about this:




$model= new AModel;

$primaryKey= $model->setAttributes($_POST['AModel'])->save()->primaryKey;



It looks like very promising and confortable, but unfotunatley right now save returns wether the saving was successfully…

If you will support extensively methiod chaining, then you will be supposed to support extensively method chaining!

Hi!

It may be a bit of confusing if some classes use chaining and some dont, no?

Yep, inconsistency is a problem and can lead to even more problems. I think I’ll roll this one back today.

If you can name classes/methods where it will look 100% consistent and usable I’ll leave ability to do chained calls in these classes/methods.

The method chaining is a powerfull thing. But as we know, a great power requires a great responsability!!!

I vote yes, but let use it with responsability.

A few considerations:

  1. there may be potential unforeseen backward compatibility problems as mentioned above

  2. debugging is somewhat harder now, for example, if a problem is somewhere in the middle of the chain, you will most likely need to tear apart the chain (i.e. write them out line by line or split into non-chained calls) to find the problem.

  3. I think if chaining is desired, it needs to be planned and designed from the beginning

I totally agree with that, such things, even though they are useful in certain scenarios, should be designed from the beginning and not added late, when there is risk of backward compatibility.

But since Yii 2.0 will be rewritten entirely maybe chaining would be a nice feature.