bash_shell

Automate everything (practical uses of Bash part 1)

I find that having a bias towards automation makes life a lot easier. I’ve been writing more and more scripts the farther along I go in my career. The time it takes to write a little script is hardly anything compared to the time it saves. I just can’t stay comfortable with typing long commands anymore. There’s a certain point where it just makes sense to script a task and that point usually comes only the second or third time I do it.

Usually I write scripts in Bash. Whether I’m on my mac or on my linux box, Bash is there.

So what are some practical uses of Bash? . . .

Care for your code

Your code is a living thing. Like any living thing, it changes constantly. Old parts die and sluff off. New parts grow to replace them. Your code goes where the customers take it. One day it needs to spend all of its waking hours in the burning sun. The next it might be whisked off to the frigid tundra. Wherever it goes, you go with it, and your code depends on you to take care of it!

Care for your code!

Let’s make sure we call out that your code needs direct care. Just like a pet, your code needs to be cleaned periodically. It also needs to be groomed. You can’t let those fingernails grow too long. You must not neglect to brush your pet. It’s important to keep up with regular medical and dental visits. Preventive care, like vaccines, are important. Apply security patches. Upgrade dependencies. Remove dead code. Make sure failing tests get fixed. I can’t forget to mention that you need to watch your code for any concerning changes. If your code starts shedding hair for no obvious reason, its not time to sit back and hope that things get better.

Care for your code!

Your code needs a lot of supporting accessories. It needs memory (physical and logical), bandwidth, and data. It also needs at least a development environment and a production environment. Most of your code needs one or more of an integration, QA, staging, UAT, and/or performance testing environment. (Maybe more.) That means you need build pipelines with build, deployment, and dependency management servers. Your code also needs supporting services and databases. Not only do you need the direct databases or services that you depend on, but you also need monitoring infrastructure.

Care for your code!

For all of these things, you should have a way to go from newly unboxed server or a newly created virtual machine to fully functioning environment in less than a day. Its best if this is automated and you do it often. The point is: just like a fish tank, the environment around your code needs care. Keep an eye on it and clean it up regularly. Change the water and the filter. Vacuum the gravel.

Care for your code!

What about regular use and inspection? Does your code get enough? Do you exercise the code? I don’t mean by your customers. End users are total strangers who have no connection with your code, and who expect you to take care of it enough that they can get done whatever they need to get done. Those people aren’t there to exercise your code. They need something from your code. If your code were a horse rented to tourists in the Grand Canyon, you wouldn’t put her in the stable at night, and take her out in the morning for the next unsuspecting sap, without going over every inch of her to make sure she’s still in shape for the task.

Care for your code!

I know it’s easy to think that code is a static entity. Just words in a file somewhere. Something that sits there and does its job. Just another company asset like a desk or a whiteboard. But this is not the case. Code is alive and code matters.

Care for your code!

duke_from_java_by_reallyn00b-d2zdiy7

Java Optional, WTF?

People say Java’s Optional is broken. And man is it ever!

Let’s say you have a value object, Name, like this:

public class Name {
    
    private String first;
    private String last;
    
    public Name(String first, String last) {
        this.first = first;
        this.last = last;
    }
    
    public String getFirst() {
        return first;
    }
    
    public String getLast() {
        return last;
    }
    
    public String getFullName() {
        return first + " " + last;
    }
}

And elsewhere you have these lines of code:

Optional<Name> optionalName = Optional.of(new Name(null, null));
Optional<String> optionalFirst = optionalName.flatMap(name -> Optional.of(name.getFirst()));

Seems totally reasonable! But when you run it:

Exception in thread "main" java.lang.NullPointerException
    at java.util.Objects.requireNonNull(Objects.java:203)
    at java.util.Optional.<init>(Optional.java:96)
    at java.util.Optional.of(Optional.java:108)
    at com.scottshipp.www.OptionalWTF1.lambda$main$0(OptionalWTF1.java:14)
    at java.util.Optional.flatMap(Optional.java:241)
    at com.scottshipp.www.OptionalWTF1.main(OptionalWTF1.java:14)

This is why Java’s Optional is broken!

Uh…no it’s not

But yeah, you’re a clever, observant person. You noticed that I didn’t use ofNullable in that example. It should be Optional.ofNullable(name.getFirst()).

So that totally works…

Optional<Name> optionalName = Optional.of(new Name(null, null));
Optional<String> optionalFirst = optionalName.flatMap(name -> Optional.ofNullable(name.getFirst()));

Uh… Yes it is

…but WTF? Why? Why is there an ofNullable method separate from the of method? Fucking everything in Java is nullable! Except
primitives but you can’t pass fucking primitives to either of these methods! What is this shit? What are they smoking at Oracle?

Scala only has Option (the apply method on the Option class) and it only does what ofNullable does and returns None if you pass it null:

case class Name(first: String, last: String)
val optionalName = Option(new Name(null, null))
val optionalFirst = optionalName.flatMap(name => Option(name.first))

No NullPointerException! The optionalFirst variable now holds a None.

I tried hard to fuck up Scala code as bad as Java and I could not get a NullPointerException out of it.

The worst part

Do you want to know the worst part of this? The part that makes me want to punch “Duke”, Java’s mascot, in the mouth?

The worst part is that NullPointerException is a runtime error!

And, clearly, this is something that the compiler could figure out. It turns out, that this NullPointerException is entirely on purpose, it’s part of the method contract for of (see its Javadoc). For what inhuman reasoning I can’t even guess.

The worst worst part

So now because of that, you can write a one-line Java program that compiles just fine but throws a NullPointerException:

public class OptionalWTF0 { public static void main(String[] args) { Optional.of(null); } }
Exception in thread "main" java.lang.NullPointerException
    at java.util.Objects.requireNonNull(Objects.java:203)
    at java.util.Optional.<init>(Optional.java:96)
    at java.util.Optional.of(Optional.java:108)
    at com.scottshipp.www.OptionalWTF0.main(OptionalWTF0.java:8)