Skip to content
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

Feature: mutations #176

Merged
merged 8 commits into from Jan 24, 2019
Merged

Feature: mutations #176

merged 8 commits into from Jan 24, 2019

Conversation

frederikbosch
Copy link
Contributor

@frederikbosch frederikbosch commented Jan 2, 2019

Adds a new feature. Allows class to be mutated after initialization. It can be seen as an abstracter method to modify the object after initialization compared to setters.

$di->mutations['Vendor\Package\Example'][] = $di->lazyNew(ExampleMutation::class);

class ExampleMutation implements MutationInterface
{
    public function __invoke(object $object): object
    {
        $object->setFoo('mutated');
        return $object;
    }
}

@frederikbosch frederikbosch changed the title New features: mutations New feature: mutations Jan 2, 2019
@frederikbosch frederikbosch changed the title New feature: mutations Feature: mutations Jan 2, 2019
@jakejohns
Copy link
Member

This is related to #147 , right?

@frederikbosch
Copy link
Contributor Author

Right

@frederikbosch
Copy link
Contributor Author

It can be used for all kinds of cases.

  1. It can structure code by to moving all $di->setters into one place.
  2. It allows complexer setters, e.g. $object->setMethod($arg1, $arg2);.
  3. It allows conditional setters, without instantiating other objects before construction of the object.
  4. It allows async decentralized modification of the object.

The first three are indeed also possible through a factory. The latter is the provider functionality I requested in #147.

{
public function mutate(object $object): object
{
$object->setFoo('mutated');
Copy link
Member

Choose a reason for hiding this comment

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

There is a problem I think. If the setters are relaying on other objects which have dependency on di then it will not work as expected right ? The mutation expects the setters are made possible via normal intantiation or string currently.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well, the mutation class itself can be constructed with the di like any other class, so it is possible to inject its depencies (other classes, config vars or even the container itself).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

A second option would be to pass the container as a second argument to the mutate method.

Copy link
Member

Choose a reason for hiding this comment

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

Yes, I think it may be good to have container object.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@harikt I had a look at it and my suggestion to pass the container as second argument is not possible after all. At least not without a large refactor because the container is not available in InjectionFactory and Factory. So in order to pass the container to the mutate method we should somehow make the container available in those two classes (inject it).

I don't know if that is worth the effort since the mutation class can already be constructed as any other class. I added another example in the docs and included some more tests. The following works without a problem. I think this is in line with the rest of the library.

$di->params['Vendor\Mutation']['argX'] = $di->lazyGet('service');
$di->params['Vendor\Mutation']['argY'] = $di;
$di->mutations['Vendor\Object'][] = $di->lazyNew('Vendor\Mutation');

@harikt
Copy link
Member

harikt commented Jan 7, 2019

Hey @frederikbosch ,

I think you want to merge 4.x branch to yours. Else the same commits are showing in the diff which makes things hard for review.

@frederikbosch
Copy link
Contributor Author

I will rebase and update the PR.

@frederikbosch
Copy link
Contributor Author

Done the rebase.


class ExampleMutation implements MutationInterface
{
public function mutate(object $object): object
Copy link
Member

Choose a reason for hiding this comment

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

I noticed the MutationInterface is having __invoke and not mutate. Also I think there need a better example. Basically in the examples you mentioned about arguments can be passed. But in the class they are missing which makes things a bit hard to digest. I am still trying to figure out the mutation and how they are working. I will look with a fresh eye later.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Aight, I will add a better example.

@frederikbosch
Copy link
Contributor Author

@harikt I added some more docs and changed mutate in __invoke. Hopefully things are a little more clear now.

throw Exception::mutationDoesNotImplementInterface($mutation);
}

$object = $mutation($object);
Copy link
Member

@harikt harikt Jan 9, 2019

Choose a reason for hiding this comment

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

Do you think we need to make sure the returned class is same for the object passed to mutation?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good thinking. I don't know for sure. I think that we should not do any checks. What would we gain from doing that?

@harikt
Copy link
Member

harikt commented Jan 9, 2019

I am good with the changes.

@frederikbosch I hope you ok with waiting a bit for anyone else who love to review code.

@frederikbosch
Copy link
Contributor Author

Sure, who would you like to review the code? Maybe we can add them as reviewers in this PR.

@frederikbosch
Copy link
Contributor Author

@harikt Is there anything I can do to get this merged?

@harikt
Copy link
Member

harikt commented Jan 24, 2019

No. Let us merge it.

@harikt harikt merged commit 095d956 into auraphp:4.x Jan 24, 2019
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.

None yet

3 participants