≡ Menu

What is the best way to inject a logger?

I’m working on several projects right now that I’d like to be able to generate logs from.

The problem is that logging isn’t required for the code to work, so how do I configure it?

I see three possibilities:

Required in Constructor

Pros

  • Cleanest implementation

Cons

  • Requires user to pass in a logger even if they don’t want to log anything

Optional in Constructor

Pros

  • No longer requires the user to pass in a logger

Cons

  • Clutters up the constructor
  • I consider using null a code smell

Optional setLogger Method

Pros

  • Clean constructor
  • No nulls

Cons

  • Instantiating with a logger requires two statements

Summary

I’m leaning toward the third method for my packages even though it doesn’t feel like an ideal solution. It just feels better than the other two.

How are you handling injecting an optional logger? Let me know in the comments.

{ 24 comments }

PSR-7 Objects Could Be Immutable

I’ve been thinking a lot about immutable objects lately. Yegor Bugayenko claims that Objects Should Be Immutable and PSR-7: HTTP message interfaces are designed to be immutable.

Messages are values where the identity is the aggregate of all parts of the message; a change to any aspect of the message is essentially a new message. This is the very definition of a value object. The practice by which changes result in a new instance is termed immutability and is a feature designed to ensure the integrity of a given value.

There has been some discussion around the mutability of streams in PSR-7.

Andrew Carter wrote a post discussing why PSR-7 Objects Are Not Immutable saying:

You shouldn’t expect to see the message that was written to the response actually rendered. The code we have written explicitly avoided returning the response by throwing the exception. However, if you disable the Whoops error handler and use the default templated error handler you will find that your message still appears at the top of the error page that is generated by the framework.

Paul M. Jones mentions the immutability of streams in Avoiding Quasi-Immutable Objects in PHP.

If a stream or similar resource has been opened in a writable (or appendable) mode, and is used as an immutable property, it should be obvious that object immutability is not preserved.

This makes sense. If you write to a stream, then rewind it and write it, the value has changed.

I don’t think this makes the class wrapping the stream mutable.

Yegor talks about this idea in Gradients of Immutability.

His argument would be that the object isn’t a constant, but it is immutable.

The object isn’t representative of the content of the stream, but of the reference to the stream.

It’s like if you had an object that interacted with a file.

You might argue that a File object isn’t immutable because if it was $f->read() should have returned “hoopla”. But I disagree.

The File object is wrapping a file name, a pointer to a file in the file system. The object isn’t constant, but it is immutable because it’s data is the file name and not the contents of the file.

I’d be breaking immutability if I added a setFilename method that allowed you to change what file the object was pointing to.

Zend Diactoros

The PSR-7 implementation that I typically use is Zend Diactoros because it’s what used by Radar.

I was hoping to dig in and show how it actually is immutable, but I can’t. Because it isn’t. 🙁

It could have been, but the Stream::attach method makes it mutable.

The strange thing is that it implements Psr\Http\Message\StreamInterface which does not define an attach method.

So Zend\Diactoros\Stream chooses to define additional methods that are not part of the PSR-7 interface, and in doing so, breaks immutability.

Guzzle PSR-7

Looking at other implementations, it would appear Guzzle PSR-7 streams are immutable.

{ 7 comments }

How Can We Colonize Mars?

I periodically read about people wanting to colonize Mars. Elon Musk seems interested in doing so. However, I’m always confused on how we can actually do that, but not in the technical sense.

According to the 1967 Outer Space Treaty, we’re forbidden from sending a mission, robot or human, close to a water source in the fear of contaminating it with life from Earth.

Isn’t colonizing a planet basically the definition of “contaminating it with life from Earth”?

I’ve always thought that it made a lot more sense to create a self-contained spaceship that people would live on indefinitely. They would have to be big enough to hold at least 10,000-40,000 people in able to preserve genetic diversity.

We could send out several of these each in different directions with the idea that only one needs to survive for the human race to continue.

The objective wouldn’t be to reach someplace specific, it would just be to continue to live, breed, develop culture, etc. Eventually, there would be a need to create more ships so landing on planets or meteors might be needed, but only for raw materials, not to colonize.

Some people along the way may decide to stay on a planet, but frankly, they would probably die unless it was a whole lot of them.

{ 0 comments }

Be the Change

Donald Trump will be the next president of the United States.

There will be a lot of negativity in the coming days. A lot of finger pointing, name calling, blaming and possibly violence. Please don’t participate in the negativity.

When people succeed they tend to party but when they fail they tend to ponder. –Tony Robbins

This is an opportunity to listen to each other. A large part of our country spoke last night. They are tired of being ignored, they are in pain. They want what all of us want. To be loved and to provide for themselves and their families.

They feel that Donald Trump is the best chance they have to change a system that they feel is hurting them. A system that is hurting their families and communities.

As a nation, we now have the opportunity to listen to each other. To understand each other and do the best we can to move forward and make this country great for all of us.

If you’re like me and are scared about what this election means for our families and communities. If you’re scared of what it means for people of color, for women, for LGBTQ people, for Muslims and Jews. Take comfort in all the good in the world.

I think that many Trump supporters are kind, caring, thoughtful people. They are not the racist, misogynistic monsters portrayed by the news.

Don’t ask why is this happening to us. But what opportunities does this present for us all to be the change we want in the world?

When I was a boy and I would see scary things in the news, my mother would say to me, “Look for the helpers. You will always find people who are helping.” –Fred Rogers

Do not shut out your friends, family or neighbors who voted differently than you yesterday. Listen. Don’t lecture or try to convince. Just listen. We are more common than different.

{ 0 comments }

What is the best git workflow for small teams?

In my development, I use Git all the time. It was a little tricky to figure out at first but, I feel like I have a good understanding of how to use it.

When I’ve worked with other developers I see them struggling with a few concepts that I use regularly and thought it might be helpful to document my workflow.

On our team, we use feature branches and pull requests. I don’t have a strong preference of whether the feature branch is in our main repo or in a developers fork of our repo. For this post, I’ll assume feature branches are in the main repo.

Let’s start with the following master branch.

I’m going to work on a new feature so I create a new branch off of master and start committing my changes.

During that time, other developers merged in features.

I’m ready to submit my PR, but first I need to rebase off of master, potentially resolving conflicts that emerge.

I need to make changes based on a code review, so I commit those to my repo. Meanwhile, other features are merged into master.

Before I have my new changes reviewed I once again need to rebase off of master.

To push up to the main repo I need to do a force push because I’m overwriting what was previously there.

My PR is accepted, so it’s squashed and merged into master as H (via GitHub), the feature branch is deleted.

Once something is merged into master it’s locked. Other than specific edge cases, you shouldn’t ever have to force push to master, only to feature branches.

With our main SaaS applications I also use Git to deploy to staging and production. I wouldn’t use this for library development or any applications that have multiple deployments.

I have special branches staging and production which our continuous integration platform watch. When I push changes into those branches they are tested (as with all pushes) and if tests pass, they are deployed to that environment.

So if we wanted to deploy my latest feature, I’d merge it into staging and have our team review it to determine if there are any issues that need to be resolved before deploying to production.

If there are changes we create a new feature branch and start at the top of this workflow.

If there are no changes to be made then we merge into production, it’s tested and deployed.

That’s it! Developers I’ve worked with tend to get hung up on rebasing. I know some workflows never rebase and always merge, but I strongly prefer keeping things clean with rebasing.

I know that there are a million ways to use Git and different teams have different workflows. What do you think of my process? Anything you’d change?

{ 0 comments }