Skip to content

[Console] Throw an exception if the Command __construct() method is not called #9186

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 1, 2013

Conversation

lyrixx
Copy link
Member

@lyrixx lyrixx commented Oct 1, 2013

Q A
Bug fix? no
New feature? yes
BC breaks? no
Deprecations? no
Tests pass? yes
license? MIT

It can only happend if the constructor has been overridden

It can only happend if the constructor has been overridden
fabpot added a commit that referenced this pull request Oct 1, 2013
…ntain aliases (lyrixx)

This PR was merged into the master branch.

Discussion
----------

[Console] Throw an exception if the command does not contain aliases

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| license?      | MIT

It can only happend if the constructor has been overridden

Commits
-------

7e5c901 [Console] Throw an exception if the command does not contain aliases
@fabpot fabpot merged commit 7e5c901 into symfony:master Oct 1, 2013
@@ -407,6 +407,10 @@ public function add(Command $command)
return;
}

if (null === $command->getAliases()) {
throw new \InvalidArgumentException(sprintf('You must call the parent constructor in "%s::__construct()"', get_class($command)));
Copy link
Member

Choose a reason for hiding this comment

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

InvalidArgumentException seems inappropriate here. UnexpectedValueException would be better.

@lyrixx lyrixx deleted the command-test branch October 1, 2013 11:25
@Tobion
Copy link
Contributor

Tobion commented Oct 1, 2013

I think adding this code is a bad idea. Do we want to add such code in all classes of symfony to see if the constructor has been called?!
This is why I prefer to initialize variables when defining them instead of the constructor: https://github.com/lyrixx/symfony/blob/7e5c9011c9e9f51f8631b75d258d4efe83ac1fbb/src/Symfony/Component/Console/Command/Command.php#L36

@lyrixx
Copy link
Member Author

lyrixx commented Oct 1, 2013

@Tobion it is very very hard, for the end user, to find this bug. So here, it is
only a safe guard. Here it is not about var initialization. It's about
overriding the constructor. I just use a hack to determine if the end user
forgot to call the parent.

@Tobion
Copy link
Contributor

Tobion commented Oct 1, 2013

Exactly, it's a hack. This is why 👎 for me. getAliases returns an array according to the phpdoc. So it should not even be allowed to return null.
If you want to add this feature for developers, it's the wrong way. You should an a new property to command that is used excatly for this use-case to determine if the constructor has been called. And not reuse buggy code.

@Tobion
Copy link
Contributor

Tobion commented Oct 1, 2013

If someone fixes that getAliases cannot return null, it will break suddenly...

@lyrixx
Copy link
Member Author

lyrixx commented Oct 1, 2013

What feature ?
About "it will break suddenly": there is tests ;)

@Tobion
Copy link
Contributor

Tobion commented Oct 1, 2013

It based on implementation detail not based on API. Cannot say more.

@Tobion
Copy link
Contributor

Tobion commented Oct 1, 2013

Btw, it's also a BC break that should be documented. For example when I override the public methods in my command, I don't need to call the parent constructor. Now my console will be broken by this exception suddenly.

@stof
Copy link
Member

stof commented Oct 1, 2013

@Tobion If you are not overriding the constructor, you will not get this exception as the inherited constructor is used.
and if you are overriding the constructor without calling the parent one, the code is already broken

@Tobion
Copy link
Contributor

Tobion commented Oct 1, 2013

@stof wrong. I can override the constructor without calling the parent, when I also override the public methods. This is absolutly valid. After this change, it does not work anymore.

@stof
Copy link
Member

stof commented Oct 1, 2013

@Tobion If you overwrite the method but respects its API, you should not reach this path either as it should return an array

@Tobion
Copy link
Contributor

Tobion commented Oct 1, 2013

I will if I did not override getAliases() because I don't want any.

@Tobion
Copy link
Contributor

Tobion commented Oct 1, 2013

@stof so you think this implementation is good?

@stof
Copy link
Member

stof commented Oct 1, 2013

Well, it is probably not the best way to do this. Ideally, we should not need to warn users about forgetting to call the parent constructor, but many users don't think about it when overwriting a constructor

fabpot added a commit that referenced this pull request Oct 31, 2013
…ion)

This PR was merged into the master branch.

Discussion
----------

[Console] make parent constructor test more reliable

| Q             | A
| ------------- | ---
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Fixes   | #9186 , f2b60e9
| Tests pass?   | yes
| license?      | MIT

It also fixes the test since f2b60e9 and improves phpdoc

The second commit improves regex performance to validate name (using possesive quantifier).

I did some basic performance tests http://3v4l.org/PuvuL
The new regex only takes 1/3 of the time compared to the old one!

Commits
-------

5798029 [Console] improve regex performance to validate name
22b09ce [Console] make parent constructor test more reliable
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants