David Ruttka

Engineering | Gaming | Improv | Storytelling | Music

If It’s Good for You, Good for You!

| Comments

tl;dr: We need to stop telling others that they’re doing it wrong just because they’re doing it differently. Different things work for different people; we should at least consider that other paths exist, even if we choose not to take them.

Y’all Be Jokin’ On Me

The other day, I saw this meme:

The instance of the tweet that I saw had about 9001 comments from both sides of the estimation debate that proved the point of the meme itself. My initial reaction was, “Yes! This observation is both humorous and valid. Often, people do indeed respond with great scepticism and dismissal when someone suggests exploring a new methodology!” The replies quickly transformed my feelings into something along the lines of “Stop arguing on Twitter about why everyone needs to do it your way!”

Different Strokes

As I said above, to me it wasn’t really about whether estimates or no estimates is the best way to do things. It was about the way people (not isolated to developers) insist that their way is the only way, and everyone else is an idiot who has never been successful with anything in their lives. It’s about how simply suggesting that an alternate path exists is treated as the incoherent babbling of a mad person.

So many are convinced that what works for them and their team is the one true way, and anyone doing something else must be converted. To such a mind, there is no need to try something else, or to even acknowledge that something else exists. Methodology, language, framework, tabs vs. spaces, and even source control1 somehow become matters of great urgency.

What if we focused instead on the value being delivered and the problems being solved? What if it’s ok to eat mashed potatoes with either a spoon or a fork, as long as the food is making it into the mouth?

Objectivity

There are certainly cases where a new technology, a new methodology, or a different source control solution can yield significant, objectively measurable improvements. There are certainly patterns which can wreak havoc on a system or compromise privacy and security. In such cases, of course we should share that knowledge. However, there are ways to make such sharing effective, and there are ways to ensure that no one takes you seriously.

Ways To Make A Point, Ranked, Edited For Length and To Make A Point

(1) References to case studies, production systems
(2) Side by side demo solutions, real world scenario
(3) Side by side code examples, contrived scenario
(4) Prose describing hypothetical situations

(9001) Popularity contest
(10001) Get really loud
(11001) Get really snarky
(NaN) Call the other person stupid

What If They Still Won’t Listen?!

Well, if we’re going to start a Dark Knight reference, we might as well wrap up with one. Symmetry!

Please do calmly, respectfully highlight of the pitfalls of pattern / framework / methodology X and how Y mitigates said pitfalls. If a person insists on moving forward with X, you’ve done the best you can. It is not your job to change a stubborn, irrational person into a thoughtful, logical one. If the dangers are real, then they’ll eventually be bitten by their willful ignorance, and maybe they’ll want to revisit the discussion. If not, then maybe those dragons you were seeing weren’t such a big deal after all, and you’ve avoided fighting over something irrelevant.

Admittedly, this is a bit more complex if it’s happening within your own team. In that case, if the dragons come, they’re eating you too. Even if they don’t come, there’s a weird air of conflict hanging around. This post was focused more on arguing with people you don’t work with about things that will not impact you. I might cover team dynamics in the future, or you can feel free to share thoughts on that (or anything else) in the comments section below2.


Footnotes:

1: I’m probably definitely guilty of getting a bit evangelical about Git, but honestly, that kind of falls under the “Truly, Objectively Better” bit ;)

2: Just remember to keep the theme of this post in mind when commenting =p

Why Doesn’t Cordova Run Windows Run the 8.1 App?

| Comments

A few years ago, I did a (very intro level) talk on PhoneGap. Recently, I’ve been getting back into Cordova for serious business — wow, have we come a long way =)

One of the things that caused me a bit of friction was that cordova run windows wasn’t working how I expected. It kept trying to run the 8.0 target of the universal app instead of the 8.1 target.

I was working around this by opening the .sln in Visual Studio and explicitly running the 8.1 project. I’d prefer not to do this.

Today I finally took a minute to search for a solution, and I found what I needed to do.

By default build command produces two packages: Windows 8.0 and Windows Phone 8.1. To upgrade Windows package version from 8.0 to 8.1 the following configuration setting must be added to configuration file (config.xml). <preference name='windows-target-version' value='8.1' />

Thanks, Sergey!

A Set of Fresh Eyes

| Comments

The other day, I saw my wife looking at a recipe book and writing in a notebook. She often looks at these books when making meal plans and grocery lists, so I didn’t think much of it. Many minutes later, she was still writing. I looked closer and realized that she was copying recipes by hand. “Have you considered taking a picture and emailing it?” The look of realization spread over her face, and we had a laugh. It turns out that she had considered scanning it, but our scanner isn’t a flatbed.

It struck me as another great example of why team communication is so powerful. She had come up with a reasonable solution, but when it didn’t work out, a narrow focus on that solution caused her to overlook a working alternative. My teammates have often found me in a similar state and gotten me rolling again with a simple “Have you considered…?”1 I immediately see the light and can usually see exactly how my initial idea put me on a train of thought that made me miss it.2

Feel free to share some times you remember when a set of fresh eyes was all it took to see a better way.3


Footnotes:

1: I’d like to think that I return the favor from time to time.

2: In addition, I usually facepalm myself.

3: Pairing can make this process continuous, but that’s for another post.

Committed to Good Commits: Work Item Association

| Comments

This is part of a series on good commits.

Ok, Mr. Anderson

Work Item Association

Another way to enhance your commits is to associate them to work items. This can help everyone on the team – present and future – understand what’s going on with the project.

What Are You Doing?

One of the most common problems I see during code reviews is that reviewers do not have a proper context for what they’re reviewing. Things devolve into something on par with copy editing with no feedback on the plot. At best, bad loops or off by one errors get caught, but there are no guarantees that the changes are covering all of the intended acceptance criteria.

What if the author could give the reviewers a pointer to something that explained what they were trying to accomplish? Something that was already on record in a shared system? Something like a work item?

How Did We Fix That?

Another great advantage of associating commits to work items is to jog memories when the ghosts of crushed bugs come back to haunt the team.

Have you ever come across a problem and thought, “This seems familiar. We fixed something like this a while ago. I just can’t remember how…”

Or, “This is a regression of what we fixed a few weeks ago, but I don’t remember exactly what we did to fix it.”

What if you could look at the old bug and know exactly which commits resolved the issue? What if you could just grep a git log for an issue number?

Test Case Generation

It can also help a test team understand what areas are at risk for regression if they know what code is changing. Put commit information on the bug when you resolve it so that they can review the changes.

Common Arguments

  1. “We don’t use issue tracking.”1 In this case, you can use the extended commit message to provide a lot of details of what your change is attempting to do.
  2. “I forgot!” This, like many things in this series, is just a matter of habit. The team can hold each other accountable, or you can find a way to enforce it via policy.
  3. “Takes too long!” Again, like many things in this series, compare it to the time spent on the change itself and to the time that will be wasted later (looking things up, discussing the intent of the code review, etc.). Seconds on hours is blue on black2.

Thoughts?

What do you think? Is adding this extra information to the public record of your project history valuable? If not, why not? If so, what other benefits have I missed? What else can we do to make it more natural for our teams?

1: I will hold my tongue on asking, “Why the hell not?!”

2: Remember that things can be automated. My teams have used server side hooks in the past so that if the message matched, for example, ^GEM:\d+, we’d automatically associate to the Gemini issue. Think about what works best for your team.

High Performance Developers

| Comments Permalink

This is a super good read.

It’s really pretty simple. I can, during that time, pair up with 10 less experienced developers and show them how to find solutions in minutes for things that would have taken them hours or days. I can make myself available to answer their questions. I can intervene at the point where they’d have thrown up their arms in frustration and despair and spent the rest of the day reading buzz feed and cracked. I can clear obstacles from their paths and help them get things done. I can get them excited about programming and enjoying their jobs.

If I were a high performing developer, but I did none of that, and just used those less experienced or less engaged developers as a prop to make the claim that I’m in some kind of elite club of “10x” people, the opportunity cost of my attitude would more than offset my skill from an industry perspective. If, instead, I help them up their game and overcome hurdles, then perhaps that 10x designation might actually mean something.

Are You Really Blocked?

| Comments

Let’s Talk About Cake

Imagine that you have been asked to make a pineapple upside down cake, as pictured below.

Think about what needs to happen here. Prepare the batter, perhaps from a boxed cake mix. Slice up some pineapples, reserving some juice for the aforementioned batter. Bake it. Flip it upside down. Put cherries on top of the finished product.

That’s a lot of stuff to do. You’ve got the pineapple. You’ve got a proper pan and all the appropriate kitchen utensils. You’ve got the oven. Cake mix? Check.

You do not yet have the cherries.

BLOCKED

It would be incredibly inefficient (and probably a play at procrastination, if not laziness) to halt production of the cake because you don’t have the cherries.

  • You could start the cake and go buy the cherries while it baked.
  • If you feel that’s unsafe, or the time in the oven is not enough to make the run, you could go get them right now.
  • You could call your roommate who is currently at the grocery store and tell them to bring the cherries.
  • You could go get the cherries after the baking is complete and the cake is cooling.

In short, possession of the cherries is not a prerequisite to get started. However, in the course of my career, I’ve seen these reactions:

  • Use it as an excuse to be blocked. Go poll Reddit until the cherry team delivers the cherries.
  • Claim to be blocked in good faith. Defer this high priority task until later, but pick up another low priority task in the meantime.
  • Go ahead and make the cake. The cherries don’t come until last, anyway1.

Push Through The Blockers

Everyone in Seattle knows about Marshawn Lynch’s 60+ yard playoff run, but I think this one is more relevant to the current discussion:

Notice how the announcers call the play over. “Lynch not gonna get anything.” He could have thought the same thing, dropped, and gone to get some water. Instead, he found a way through the blockers and moved the ball – moved his team – forward.

This Is Not Cake Or Football

Correct! Which means you don’t have to go to the grocery store or keep your legs moving through a wall of defenders. You have a vast array of resources and tools — both inside and outside your team — that allow you to clear a path.

  • Service you depend on goes down? Fiddle it. Stub it. Introduce an early return of hardcoded data before the call is made.
  • Error you’ve never seen before? Go to Stack Overflow. Talk to your team.
  • UX Design incomplete? Implement non-UX logic. Create independent views that put unstyled data on the screen. Add styles and navigation affordances later.

We could go on.

When Truly Blocked

  • If there’s a real blocker that cannot be worked around, pick up the next task you can handle.
  • If there’s a real blocker for every task that you know how to handle, then pick one up that drives you to learn something new.
  • If there’s a real blocker for every task across the entire project, your organization has bigger problems.

The point is that there’s usually a way to move your team forward. You might not always see the way, but that’s what talking to your team if for =).

What’s your favorite story about making progress despite something that others called a blocker?

1 – Software doesn’t go stale or spoil as fast as cake. Use caution if attempting with real cake.

Cake image used under CC BY 2.0, Kimbery Vardeman

Git Pushit

| Comments

I wanted to do something silly this morning, so here’s my newest git alias.

git config --global alias.pushit '!f() { git push; start http://druttka.github.io/pushit ; }; f'

This will do a git push and then open a browser. The browser will either play “Push It” by Salt-N-Pepa or “Push It” by Static-X.

You Are Not in a Relationship With Your Tools

| Comments

Note: I haven’t forgotten or abandoned the Committed series.

Yesterday, I was beginning to prepare an internal talk, and I referred to some old materials I used when doing similar talks for previous teams. These talks go back years, and the concepts in them go back even further. Still, I see a lot of resistance to one of the ideas in particular.

tl;dr – Languages, platforms, libs, frameworks, and tools are not looking for a monogamous relationship. You don’t need to marry one and use it exclusively, nor do you need to leave one to experiment with another. The more the merrier. If you really must crush on your tools, at least be polyamorous.

Rewind: The Technology Council

I cannot make this up. I was once in a position where the grand plan was to create a sub-team of four(ish?) engineers called The Technology Council. To be fair, I can’t remember if that was the official name, or just what those of us in the trenches started calling it.

These engineers would not touch production code much any more. Their responsibility would be to create an allow list of libraries and frameworks that the other developers would be allowed to reference. Removed from the actual problems, they’d be able to see more clearly which tools would solve them. Of course, it goes without saying that once a single tool was chosen for Problem X, it would suit Problems Y and Z just fine.

Revolt

I expressed my displeasure with this idea. How could developers stay up to date or experiment with new approaches if they had to wait months for council approval? Then, when I eventually resigned, I was told I could be on the council if I’d stay. Apparently there was some confusion, and it was believed that I just wanted to be one of the deciders.

Before I left, I gave my team an internal talk called (prepare to facepalm) “Enterprise Agility – Surviving the Waterfall and Staying Sane to Boot.” Despite the title, I still stand behind most of the ideas in that talk, especially since they were heavily inspired by a (much better) talk I had just seen at CodeStock1.

One of the slides in my talk was titled “A Word About Golden Hammers.” Here’s one of the quotes I had in my notes.

What I am against is the thought that there is one solution to all problems, or that all problems can be solved by one solution. Every problem is different. The key, and the most important thing of all, is to understand not only what you’re using (framework, libraries, etc), but why that’s the right tool for the job. – Anthony Ferrara

The New Hotness vs. Legacy Rot

Have you recently heard anyone mocking someone else’s use of jQuery 1.6? Are you simultaneously locking into Angular so hard that you think your blog is a SPA? If so, you will be the jQuery 1.6 of five years from now2.

jQuery solved some very real problems, and arguably still does. There was a time when if you didn’t have a $(function(){...}), your reputation as a professional web developer would be in serious question!

Huh? –> This is really cool –> I use it everywhere –> Hmm, sometimes it’s not so great. – Mike Hadlow

Don’t let angular.module(...).run(...) be your $(function(){...}).

More Than You Need

These days, people cast dispersions $('#fancyDiv'), touting the power and simplicity of vanilla.js’s document.getElementById('fancyDiv').

These people often simultaneously take a dependency on the entirety of Bootstrap because they want their buttons to be blue. What follows is a lot of headaches and tweaks trying to comply with Bootstrap’s opinions.

I feel like there is always the “one true way”. The way the tool wants me to do it. … Need another way? That’s gonna be a lot of work. The “one true way” makes me feel like I am driving a slot car. There is nowhere else to go. – Rob Maher

More ironically, what follows is a lot of headaches are tweaks trying to make things look less like Bootstrap and more like what the UI/UX folks really wanted. This becomes a lot harder than the couple of lines of less or sass that would have just made that button blue.

Weapon of Choice

Mastery of a single weapon or superpower will allow you to tackle a certain set of scenarios with grace and ease, but there’s a reason that teams like The Avengers and Justice League exist. It’s rare that any one skill or power will enable you to be the hero of all conflicts.

Instead of a single weapon, what you could instead have is a utility belt. For your superpower, you could choose a curious mind and sharp, critical thinking. Then you could reason about which gadget will best get you out of each jam.

Always be yourself. Unless you can be Batman. Always be Batman. – unknown source, no less true

Disillusionment

If you decide to start using X more than the Y you were using, you aren’t “leaving” the former for the latter. At least, you don’t need to do so. If you do so, no one cares.

Please do tell us what you’re learning and exploring in X. This is how we learn and grow. What I’d like to see recognized more is that adopting X does not imply that Y gets thrown into the bin. Y’s strengths are not removed by your new discovery of X. It could very well still have value in certain applications.

Wrapping This Up

The other day I was asked what tools and languages I’m using right now to get my job done. I very honestly replied that I’ve been working with a wide variety of things including but not limited to C#, node, PowerShell, and bash. The people I work with closely and I believe in familiarizing ourselves with many options, knowing their strengths and weaknesses, and utilizing the right tool for each task. We are building components that do their job and do it well, and then composing those to create the big picture solution. I hope this concept will become more mainstream in the industry. I hope I will never have to explain again why I know both PowerShell and Node, or why I’ve started learning golang along with them.

1 – Phil Japikse’s talk was called Lessons Learned: Being Agile in a Waterfall World
2 – Or, at our accelerated rate of change, five weeks from now.

Education and Experience

| Comments

Note: This is dated July 23, but it really happened and most of it was drafted on July 8. I guess we see where finishing up blog posts sits on my personal backlog.

We’ve got some interns. I paired with one of them this morning, and we performed a mild refactoring in the area of dependency injection. What we did isn’t the point of this post. The point of this post is that he asked me later in the hallway (quoted as close as I can recall):

How did you learn all this stuff and make it so your code doesn’t look like college student code?

tl;dr – Experience.

jklolThe Evolution of A Software Engineer

I’ve said for quite some time that the purpose of formal education in our industry isn’t actually to teach you what you need to know in “the real world.” Its true value is in teaching you how to learn the things you’ll need to know. It’s important to realize that going to college and paying for a piece of paper isn’t the only way to gain this skill, just one way.

Learning On the Job, Apprenticeships, Mentoring

The truth is that once you leave the school setting, there’s a world of crap you weren’t taught. Like how to use source control properly. Like team specific conventions. Like navigating an existing codebase larger than you’ve ever seen and fixing a bug without breaking anything else. Like doing that when there are no docs, no tests, and none of the original authors hanging around to answer questions.

So one part of my answer to the intern was a collection of things that fall under the “experience” heading.

  1. Find a mentor and/or engage in pair programming
  2. Pay attention to what works well for you and what doesn’t
  3. Request feedback through channels like code review
  4. Read the code that your team is writing
  5. Use the magic of open source to do all of the above with the entire world, not just the people at your workplace!

I could do a whole post on pairing itself, or perhaps a whole series on pairing itself. All of these have value, though. The lowest common denominator is share and spread awareness of what people are doing, and pay attention.

Constant Learning

Our toolchains are very volatile. We need to be constant learners if we hope to work on interesting projects, or even to be employable until retirement age. I’ve seen colleagues who started their careers in VB6 have a hard time finding new jobs when inevitable layoffs or collapses occur because they never took the time to learn anything else.

The other part of my answer to the intern was a collection of things that fall under the “continuing education” heading.

  1. Find some books.
    1. You want some like Clean Code and Think Like A Programmer – general, conceptual, technology agnostic.
    2. You want some others that dive deep into the technology stack you’re using, like C# in Depth or JavaScript the Good Parts.
  2. Subscribe to some blogs or podcasts that cover the things you’re directly working with.
  3. Subscribe to more that cover areas you’re interested in, but not yet working with. It helps to get your head around those concepts and the vocabulary.
  4. Subscribe to still more that cover areas you’re not touching at all. See how the other half thinks, and reflect on whether what they’re doing could apply to where you are.
  5. Subscribe to some aggregators that collect a daily dose of ideas, new tech, tutorials, etc. Stay aware of what’s out there.
  6. Attend conferences, either physically or virtually, to get a sense of what’s going on beyond your own experience.
  7. For all of the above, do not blindly accept everything anyone says. Think.

The question usually becomes, “Isn’t that a lot of reading and listening to do? When you do actually WORK?” The answer is that you don’t have to read it all. You’re looking for headlines to keep you aware of what’s happening, skimming to evaluate what’s important, and you choosing which ones are worth a full read. You control your own destiny. I have 79 sources in the “Development” category of my RSS reader, and I spend 15 minutes, maybe 30 max, each morning.

To steal (and perhaps repurpose) a talk title,

It’s not what you read, it’s what you ignore. – Scott Hanselman

And that’s all I have to say about that.

Committed to Good Commits: Validation

| Comments

This is part of a series. The full list of posts can be found in the introduction.

A note before I start. I heard through the grapevine that a previous post in this series gained some popularity, and that some people held the opinion that these things are too obvious to be posting about.

Why are you sharing this? People should already know this!

Like I said in the introduction, these things are unfortunately not that obvious to many people. If every person across every team that you’ve ever worked on was on board with this stuff, you are either incredibly lucky or incredibly young. Until then, we should not feel that it is “too obvious” to discuss. Those with less exposure need to hear it. Perhaps even we who think we have a handle on proper use of source control still have more to learn from others even wiser than ourselves.

Now, where were we…

Oh, ya.

Validation

Usually, when I delivered this content as a talk, the “Validation” slide came later in the progression. I’m switching it up a little for the blog post series because without proper validation, a lot of hard work can suddenly be all for naught.

Don’t. Pollute. The. Stream.

Source control should be a safe place. Bad things are going to happen from time to time, but it should be the exception, not the rule. There are ways to be confident that you’re going to keep things clean and happy for yourself and your team.

Here are a few simple things that you can do before you push (or check-in, or whatever your source control calls putting your changes into a place where they’ll directly affect your team).

I consider this to be the minimum bar of respect and consideration for others on my team, and I feel bad if I realize I skip them1.

  1. Make sure you’re at least syntactically sound (compile, or lint, or what have you)
  2. Confirm that the app can actually start running
  3. Run whatever tests you have against your changes2
  4. Check status / diff to confirm that only the changes you intend to include are included
    1. Do you have test / debug code that should be reverted?
    2. Do you have local config changes that should be reverted?
    3. Did your tooling do anything ridiculous when you weren’t looking? (cough cough ReDerper3 cough)

Why?

Because no one wants to pull the latest changes and be blocked by a broken build, or by being unable to start, or by seeing work they did two weeks ago suddenly disappear because you resolved conflicts backwards.

Why not?

Some of the common points of resistance I’ve heard…

  1. Not in the habit. Ok, make it habit. Put some form of accountability in place that encourages people to keep things clean. I’ve heard of donating $1 each time you break it, or having to take over deployments until the next time someone breaks it. I’ve heard of dashboards and sirens and traffic lights. I’ve heard of going the other way and creating rewards for those who break it LEAST. Depending on your team culture, there’s a lot you could do here.
  2. Too much time. We’ll get to some specific ways to make all of this faster below, but even without those, think about the time you’re going to lose if you just slam code into the repo without paying attention. Time determining which of the recent pushes introduced the problem. Time your coworkers lose unable to build while waiting for it to get fixed. Time chasing bugs that really just come down to a hacky line you put in for local testing and forgot to take out because you didn’t diff.

Making This Easier

Here are some things that I’ve found can reduce some of the friction around validation.

  1. Automate all the things. If a task runner is watching your changes and constantly running tests, notifying you if they break, you can fix it before it becomes a bigger problem. gulp watch is your friend!
  2. Code review. Looking back over a unified diff helps catch a lot of those “config oops” moments, typos, and weird things that tooling does to “help us” .
  3. We’re working on topic branches right now. If I push something awful, only the people working on that topic are affected (at least, that is, until the topic is merged). Note that this doesn’t give us an exemption from validating our changes, but in case we forget…
  4. Automate even more things. Michael and I just finished setting up a process for our team that can run various validations whenever new code is pushed to any branch. We also have a dashboard that gives us visibility of the status of each branch at a glance.

What else?

You tell me. I’m sure there are a lot of things we could be doing even better.

[1] You should, too.

[2] Be sure you’re running integration/functional tests against an environment that actually, you know, has those changes.

[3] Mostly kidding. ReSharper has some great features. It’s just…sometimes…well, I think it might drink a little is all.