Skip to content
This repository was archived by the owner on Jan 31, 2020. It is now read-only.

Conversation

0xPaul
Copy link

@0xPaul 0xPaul commented Feb 12, 2017

Merely declaring a class abstract does not correctly convey intent nor prevent misuse. By marking the class final we prevent extension and by using the StaticClass trait we prevent instantiation.

"require": {
"php": "^5.6 || ^7.0"
"php": "^5.6 || ^7.0",
"scriptfusion/static-class": "^1"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dependency is to be avoided for this very internal use-case

Copy link
Author

@0xPaul 0xPaul Feb 13, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand, however the dependency only does exactly what this use-case requires and prevents code duplication, and nothing more, thus I think it is appropriate. Moreover, one might opine it reads more intuitively than writing a private constructor by conveying to the reader that the class is static, without need for additional commentary or documentation.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but that's not going to happen due to two reasons:

  • it creates a dependency for all packages relying on stdlib (ref
  • use-case scenario is tiny: 2LOC (vs 1LOC) per class in this package
  • it is not a package in ZF, therefore you have to have a stability that is either equivalent or better than ZF's in order to include it

Copy link
Author

@0xPaul 0xPaul Feb 13, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • I understand this is a core package, however this is also a common pattern and it would be my intention to introduce this trait to the wider framework since the static utility class pattern is common enough to warrant this.
  • I believe a private constructor is at least 3LOC if you respect PSR-2; 4LOC if you annotate that the empty constructor is intentional, as in the trait.
  • I do not understand what you mean. StaticClass is tagged as 1.0.0 (stable). If this is not good enough what else do you need?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Ocramius If you're not going to respond to these points and flatly refuse to use StaticClass you can close this PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand this is a core package, however this is also a common pattern and it would be my intention to introduce this trait to the wider framework since the static utility class pattern is common enough to warrant this.

True, having a common package is useful here, and I even wrote one myself ( https://github.com/Roave/Dont ), and yes, it also uses traits.

I believe a private constructor is at least 3LOC if you respect PSR-2; 4LOC if you annotate that the empty constructor is intentional, as in the trait

Yes, that's still very tiny, and a non-functional change too. Better than a static reference to an external symbol, and an additional autoloading requirement.

I do not understand what you mean. StaticClass is tagged as 1.0.0 (stable). If this is not good enough what else do you need?

Adding a dependency just for this, where the dependency has a stability and maintenance guarantees lower than the ones in the framework (with all good intent and faith, it's a package maintained by a single developer, and not by the framework team) is a problem.

This is especially true when the package is at the top of the hierarchy (zend-stdlib is used everywhere).

Please don't take this as mistrust, I'm just telling you that the implications are bigger than the gains, and that by a lot.

Copy link
Author

@0xPaul 0xPaul Mar 22, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy it to your don't package, then.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can do, but won't suggest roave/dont for inclusion here either

abstract class ArrayUtils
final class ArrayUtils
{
use StaticClass;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make the constructor private instead

Copy link
Author

@0xPaul 0xPaul Feb 13, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what the trait does.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, and it's an additional dependency and autoloaded trait (not to mention all the mess that traits lead to at reflection level) on a very, very core dependency.

A private constructor is more expressive than an imported trait in this case.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you not think a trait called static class conveys intent clearer than an anonymous private constructor?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@0xPaul you are indeed correct that static class conveys intent in a clearer way. What isn't clear is how the contract of the class is changed based on that trait by looking at this class.

A private constructor does convey that immediately, but indeed does not express what the meaning is (although developers usually understand that immediately).

abstract class ErrorHandler
final class ErrorHandler
{
use StaticClass;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make the constructor private instead

abstract class Glob
final class Glob
{
use StaticClass;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make the constructor private instead

abstract class StringUtils
final class StringUtils
{
use StaticClass;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make the constructor private instead

@0xPaul
Copy link
Author

0xPaul commented Mar 22, 2017

Loggerheads.

@Ocramius
Copy link
Member

@0xPaul please don't be like that: I really am just doing my job as gatekeeper :|

@0xPaul
Copy link
Author

0xPaul commented Mar 22, 2017

Good job.

@Ocramius
Copy link
Member

Urgh, wth, are @0xPaul and @Bilge aliases? (Yes, I just noticed the commit author)

@weierophinney weierophinney removed this from the 4.0.0 milestone Mar 22, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants