Wednesday, September 7, 2011

Titles, and why you SHOULD care.

Until recently, I didn't care too much about my own job title. Why? If you're like me, you probably come in, do your work, and go home. For some, this means a nine-to-fiver, but for others like myself, this really means your day-to-day doesn't differ all that much. Titles don't play a big role in a life like this. There wasn't a whole lot of difference in my day-to-day between when I was a "Software Engineer" and a "Senior Software Engineer". Chances are there wouldn't be a big difference between being a "Senior Software Engineer" and a "Principal Engineer" either. Sure, you will be expected to have more responsibilities, but you were probably already performing them months before anyone noticed and cared enough to promote you. So getting the title change doesn't really change your day-to-day.

So why should you care about your job title?

Three reasons:
  1. Respect
  2. Money
  3. You manage people
Respect

As I said above, until recently I didn't really care about my own job title. "What happened?", you ask?

Well, during a couple of interviews at my previous job I had two guys react very strangely to me asking them the questions I did. They seemed genuinely surprised at... well, me. I'd like to think it was because I was asking them hard questions, but the surprise came after they asked the usual, "So what do you do here?". During this time I was very happily working on a team with very senior people. The team consisted of three Principal Engineers, two Sr. Software Engineers, and was managed by the Sr. Software Architect (six total, including myself - two of the guys had Doctorates). So very intelligent people put together to do some very cool and smart work (toot toot). After explaining the team to them, and the work we were doing, both interviewees seemed very perplexed and commented on and questioned me why the interview schedule had me listed as a "Software Engineer". If this wasn't a weird enough reaction, one of the guys actually went back and started to elaborate on some of the answers he'd given me previously. It's as if, suddenly I wasn't just some young looking dude they'd put on the schedule to fill in time. Now I was someone who actually mattered. Obviously, they should have been taking the interview seriously from the start, but the reaction really surprised me - The difference three little characters could make, "Sr.".

I think it's obvious where I'm going with this. You should care about your own job title, not necessarily for yourself, but because others do. At least, you should care enough to make sure it's right on an interview schedule.

Money

In the past, there's only ever been one situation when I have really cared about my title - when I was thinking about looking for a new job, or interviewing for one.

With the expected title comes a certain level of compensation. If you're interviewing for a Sr. Software Engineer position, you expect to make more than a Software Engineer position. The same goes for all positions. If you're a Sr. Software Engineer, and you're interviewing for a Manager position, you expect more money - after all, you're expected to have more responsibility, right?

Managing People

Lastly, you should care about titles when you're managing people. In this aspect it should be their title you're concerned with.

Titles for your people are goals for them. They're stepping stones, trails, paths or roads in their careers.

To some degree, I think that if you're managing people, and you don't care about their titles, then you don't care enough for them.

I've been very fortunate to have great mentors and managers. They've all said that their jobs are making sure I'm happy, and that I'm feeling good about my future - not just ME, but EVERYONE who works for them.

By providing your people with titles and helping them to get to the next one, you're furthering their careers, helping some of them with that all important first impression, and showing them you care about their future.




I know it's lame, and none of this would really matter if people actually didn't care about titles, but unfortunately, that's not how the world works. Until someone actually meets or works with you first-hand and sees what you're capable of, your title is part of what limited information they know about you through your emails, resumes, blogs, and business cards. It helps them set up their expectations for you.

In the end, I still don't worry a lot about my own title. I'm definitely not going to obsess over it (after writing this blog). I feel like I have the respect of my colleagues and peers and I respect them, and that's what's really important to me. I'm just going to be more conscious about what my job title is, instead of not caring at all.

Monday, May 30, 2011

Some DSL fun with Groovy 1.8

One of my colleagues at work was recently tasked with creating a query language for the new integrated infrastructure we're building out. I think he is ultimately going to go with NodeJS, but after reading Groovy's recent 1.8.0 release notes, I thought I'd try my hand at doing with Groovy.

I typically like to work towards a good goal, so I started with a few directional ideas for what I wanted the language to look like. First, the new language is going to be internally (and perhaps externally) referred to as CQL (pronounced cee-que-el), not to be mistaken for SQL (ceequel). So I wanted the language itself to differentiate itself. That rules out stuff like, "select foo from bar where foo.id = 'foo1'".

Second, I've long had a preference for "finder" methods over "getter" methods for data-access level classes. This also happens to go along with Grails' dynamic finders. So, I wanted to stay away from a language like "get user where firstname = 'foo' and lastname = 'bar'". Personally, I find the "find by" language much more user friendly anyway.

With these ideas in mind, and not having a ton of experience with the new command chains in Groovy, my rough goal was to create something like this:
find entity by someField: "value" or by someOtherField: "value"

Here is what I actually ended up with:
find user("email", "firstName") by email: "eric@example.com" or email: "eberry@example.com"

Pretty darn close, perhaps even better actually. There's a nice way to specify which fields from User that I really want, and I think it really reads well.

This actually translates to this with parenthesis and dots:
find(user("email", "firstName")).by(email: "eric@example.com").or(email: eberry@example.com")

Here's how I did it.
First let's take care of the find, and user methods:
def find(it) { it }
def user(String[] fields = [] ) {
   new UserFinder(fields: fields as Set)
}
Basically the 'find' method is just for syntax sake, it's really not needed and simply returns whatever object is passed into it. In this case, it's going to be a UserFinder which is created by the 'user' method.

This gives us a nice encapsulation of concerns, the UserFinder is responsible for finding users.
class UserFinder {
   Set fields
   Map byFields
   Map orFields
   UserFinder by(Map byFields) {
      this.byFields = byFields
      return this
   }
   UserFinder or(Map orFields) {
      this.orFields = orFields
      return this
   }
   def find() {
      ... do find work ...
   }
}


That's really it. Note that since both the 'by' and the 'or' methods take maps you could provide multiple fields there, eg:
find user("firstName", "lastName") by email: "eric@example.com", id: 1 or email: "eberry@example.com", id: 2

Some benefits I see with this approach is that it's easy to separate out the concerns. The "Finder" classes are responsible for doing the actual finding. A groovy script template can be created, and be set up so that the 'user' function and classes are imported, which makes it easy to figure out what functionality is available. Obviously some sanitisation of user queries needs to be done, but besides that execution of user supplied queries is quite safe as the only methods that can be called are those that are provided within the script template. Lastly, groovydoc could be used to produce some documentation without a lot of extra work.

Another interesting idea might be to actually provide a client library which would mean the end user could build these queries in code, and it would look exactly the same as it would be sent over.

Cheers.
Eric

Thursday, May 5, 2011

A Gradle Templates plugin

I'm almost done with my Gradle Templates plugin. All the information on how to use it can be found on it's wiki page. All that's really needed now is to finish up the Scala support.

I'm pretty happy with the result. The plugin supports all the built in Gradle plugins: Java, Groovy, War (webapp), and soon Scala. It also has tasks for starting your own standalone Gradle Plugin.

It's my hope that this plugin will be helpful to others getting started with the Gradle build system.

A Quick Start:
To start using the plugin you need to have Gradle, and Bazaar VCS installed.

Then you install the plugin by downloading the source and running the 'installPlugin' task.

bzr branch lp:gradle-templates

Or if you prefer Git, there is a github mirror.

Then run the installPlugin task in the newly checked out project.

gradle installPlugin

Usually, I do all my development work in a directory under my home directory like so:
/home/elberry/development/projects
So to use the 'create*Project' tasks, I've created a build.gradle file under my 'projects' directory, which simply contains the following:
apply plugin: "templates"
This provides me with the following "Template" tasks (running 'gradle tasks').
Template tasks
--------------
createGradlePlugin - Creates a new Gradle Plugin project in a new directory named after your project.
createGroovyClass - Creates a new Groovy class in the current project.
createGroovyProject - Creates a new Gradle Groovy project in a new directory named after your project.
createJavaClass - Creates a new Java class in the current project.
createJavaProject - Creates a new Gradle Java project in a new directory named after your project.
createScalaClass - Creates a new Scala class in the current project.
createScalaProject - Creates a new Gradle Scala project in a new directory named after your project.
createWebappProject - Creates a new Gradle Webapp project in a new directory named after your project.
initGradlePlugin - Initializes a new Gradle Plugin project in the current directory.
initGroovyProject - Initializes a new Gradle Groovy project in the current directory.
initJavaProject - Initializes a new Gradle Java project in the current directory.
initScalaProject - Initializes a new Gradle Scala project in the current directory.
initWebappProject - Initializes a new Gradle Webapp project in the current directory.

As explained in the wiki, the 'create*Project' tasks are intended for creating new projects, and new directories. The 'init*Project' tasks are intended to be used within a previously created directory where you want to set this directory up as a new Gradle project.

So, to get started with your own webapp, you can now run 'gradle createWebappProject'.

Answer a few basic questions:
[503] gradle createWebappProject
> Building > :createWebappProject
??> Project Name: TestWebappProject

??> Use Jetty Plugin? (Y|n)[n] y
:createWebappProject

BUILD SUCCESSFUL

Total time: 13.207 secs

And you're done. You can 'cd' into your new project and run 'gradle jettyRun' and have your webapp up and running on port 8080 in no time.

Cheers, and happy coding. :)
Eric

Saturday, April 9, 2011

Gradle, Groovy, and MethodMissing

I've created a few of these, but I think my latest is the cleanest implementation I've done yet. I've created a new ProjectTemplate builder for laying out new projects from scratch. Why, you ask? Because I seem to be always creating new projects and importing them into my IDE. Or, I use the IDE to create them and then wind up with a bunch of IDE files stuck in source control. Personally, I prefer the former.

Normally creating the initial project structure isn't that big of a deal, it's just a few simple *nix commands really:
mkdir -p MyProject/src/
cd MyProject/src
mkdir -p main/java main/resources test/java test/resources

I could just create a small bash script to handle this for me, but I'd have to change it around all the time to handle the project name, or if I wanted to use Groovy instead of Java, etc... I could also just make the bash script handle user input, but I'd still want to set the project up with some sort of build system, and it'd be cool if the build system could do this for me.

As I've been a fan of Gradle for a while now, I wanted to see if I could do something to get Gradle to do this for me. I know Maven can do this already with archetypes, but as I said, I wanted Gradle to be able to do this for me.

Without getting into the Gradle bit too much just yet, because I want to do that properly, and it's a whole other ball of wax, I'll focus on the Groovy bits first.

So, the goal is to have a small-ish Gradle build script that'll let me create a directory structure for a new Groovy project. A pretty standard directory structure looks like this:
[project root]/
   src/
      main/
         groovy/
         resources/
      test/
         groovy/
         resources/
Let's start with a basic Gradle build script: build.gradle
task "create-groovy-project" << {
   String projectName = System.console().readLine("> Project Name: ")
   println "Creating directory structure for new Groovy project: ${projectName}"
}

Running 'gradle create-groovy-project' now results in us being asked for our new project's name, and then it being echoed back at us.

Now for a little Groovy fun. Here's a shortened version of my ProjectTemplate class. This should just be pasted into the top of your build.gradle file.
class ProjectTemplate {
   
   private File parent
   
   private ProjectTemplate() {}
   
   static void root(String path, Closure closure) {
      new ProjectTemplate().d(path, closure)
   }

   void d(String name, Closure closure = {}) {
      File oldParent = parent
      if (parent) {
         parent = new File(parent, name)
      } else {
         parent = new File(name)
      }
      parent.mkdirs()
      closure.delegate = this
      closure()
      parent = oldParent
   }
   void f(Map args = [:], String name) {
      File file
      if (parent) {
         file = new File(parent, name)
      } else {
         file = new File(name)
      }
      file.exists() ?: file.createNewFile()
      if (args.content) {
         def content = args.content.stripIndent()
         if (args.append) {
            file.append(content)
         } else {
            file.text = content
         }
      }
   }
}
Nothing too spiffy about it. You use it by calling the static 'root' method and then declaring your directories and files. Let's add it to our 'create-groovy-project' task:
task "create-groovy-project" << {
   String projectName = System.console().readLine("> Project Name: ")
   println "Creating directory structure for new Groovy project: ${projectName}"
   ProjectTemplate.root(projectName) {
      d("src") {
         d("main") {
            d("groovy")
            d("resources")
         }
         d("test") {
            d("groovy")
            d("resources")
         }
      }
      f("LICENSE.txt", content: "// LICENSE GOES HERE")
      f("README.txt", content: "// What is this project all about, and what's needed to build it?")
   }
}
Running 'gradle create-groovy-project' now, and giving the name "MyProject" results in a new directory called "MyProject" which contains a directory structure like:
MyProject/
   src/
      main/
         groovy/
         resources/
      test/
         groovy/
         resources/
   LICENSE.txt
   README.txt
Ok, so far, so good. We can now create basic directory structures for a new Groovy project, and it wouldn't be too hard at all to create an 'create-java-project', or 'create-scala-project' task now to create directory structures for those types of projects.

But the ProjectTemplate usage is still a little noisy for me. We can get rid of the parenthesis, but it's still not enough.

Let's add a methodMissing method to the ProjectTemplate class to make things cleaner:
def methodMissing(String name, def args) {
      if (args) {
         def arg = args[0]
         if (arg instanceof Closure) {
            d(name, arg)
         } else if (arg instanceof Map) {
            f(arg, name)
         } else if (arg instanceof String || arg instanceof GString) {
            f([content: arg], name)
         } else {
            println "Couldn't figure out what to do. name: ${name}, arg: ${arg}, type: ${arg.getClass()}"
         }
      }
   }
What does this buy us? Well, now we don't need to specify the method name anymore. That's right kiddies, no more d's or f's. :)

We can change our usage to this now:
ProjectTemplate.root(projectName) {
      "src" {
         "main" {
            "groovy" {}
            "resources" {}
         }
         "test" {
            "groovy" {}
            "resources" {}
         }
      }
      "LICENSE.txt" "// LICENSE GOES HERE"
      "README.txt" "// What is this project all about, and what's needed to build it?"
   }
This is a lot cleaner, and easier to read to me.

I am actually working on a Gradle plugin which I hope to make available very soon, but for now It's hosted at LaunchPad

You can download the source using Bazaar:
bzr branch lp:gradle-templates
I've uploaded the complete build.gradle file on TellurianRing.com (1).

I'll blog more about my Gradle plugin endeavors as they happen.

Cheers,
Eric

(1) build.gradle (right click and save as)

Monday, March 7, 2011

More jEdit mode-ulation

A small group of my fellow developers at eHarmony Inc. have been trying out ATDD (Acceptance Test Driven Development) with quite a bit of success, I hear. They've been using Spock to create their tests.

I too have been trying out ATDD, more specifically BDD (Behavior Driven Development) while developing TeamMochi. I found myself writing out behavioral tests in plain text first before moving them over to something like Spock. Again, I found myself doing so in my favorite text editor jEdit, and given my recent trials with jEdit's mode files, I created another mode file to help myself with creating these tests.

The mode file supports the main keywords like, "given", "when", "then", and some extra ones like: "where", "if", "and", "but", and "should". It also supports variable placeholders, and some simple markup for variable data.

All this boils down to a simple syntax highlighted user story using the normal BDD language.

Eg. A basic story like:
Given that the User is on the website
and the User is registered with the email 'kyle@example.com' and password 'password'
When the user attempts to login with his registered email and password
Then the User should be logged in and taken to his dashboard.
Looks like this in jEdit:


You'll notice that I borrowed the entity recognition from my 'domain' mode. Any word that starts with a capital appears as a label in jEdit.

This might be something given to you by the Product Owner, or preferably something you and the Product Owner came up with together.

But the developer might want to take it a step further and supply data which can be used in the test.

This is where variable placeholders, and the simple markup comes in to play.

We might for instance replace the actual email address and password in the previous example with variables, then create a "where" clause with a table of valid email addresses, and passwords for test accounts.

The text would look something like this:
Given that the User is on the website
and the User is registered with a valid email and password
When the user attempts to login with his registered ${email} and ${password}
Then the User should be logged in and taken to his dashboard.
Where (
    |= email             =|= password =|
    | 'kyle@example.com'  | 'password' |
    | 'kenny@example.com' | 'password' |
)
jEdit would show:

It also supports key, value pair markup like so:

I don't have any plans of including this mode file in jEdit core, but I've uploaded it to the daily-build server (1).

Enjoy :)

(1) behavior-test.xml (right click and save as)

Tuesday, March 1, 2011

jEdit mode-ulation

I've been playing around with jEdit mode files again. Came up with one I've committed to jEdit core, and another one I've been using with my work on TeamMochi. Both work really well with folding set to 'indent', and wrap style set to 'soft'.

The first one is a simple outline mode file which sets up syntax highlighting.

Text from WikiPedia
 As I mentioned, this mode file has been committed to jEdit core, and is available in the jEdit daily builds (1). I've also made the individual mode file available as well (2).

The second mode file is one for "domain" type text. Again, just simple syntax highlighting for what I consider a simple domain specific language (DSL).

This one is not available in jEdit core, but I've uploaded it to the daily-build server also (3).

Cheers.
Eric

(1) jEdit Daily Build (trunk)
(2) outline.xml (right click, and save as)
(3) domain.xml (right click, and save as)