5 Tips for Readable Code

I’m a cranky programmer. I’m old and approaching curmudgeon status when it comes to code. I fully expect my colleagues to eventually lock me in a back room somewhere to wait for the mysterious “double flash.” I don’t know how I got here, but I’m here now and I know that I MUCH prefer readable code. Like it or not, there’s a very good chance that someday you’ll have to “open the kimono” and allow other developers to read, and even *gulp* modify code you’ve written. As a consultant, I’ve come into some code that is very easy to read, as well as come into some code that is next to impossible to decipher. Don’t get me wrong, I’m very certain I’ve written some code that has been hard to decipher and probably still do. However, one thing I learned when writing Python code in my previous life was that explicit can be a beautiful thing. Although its entirely focused on Python, a read-through of PEP-8 can do wonders for your code’s readability by getting you to think about a consistent style. I’ve not seen a coding “style guide” from the Apex world (I’ve found this and hope it gains some ground. I haven’t had a chance to consume it all yet, but its a start). That being said, the point of this is not to get into the specifics of a particular language but rather points to ponder in a hopefully “language agnostic” manner.

  1. Method Names: Luckily I’ve not seen the proliferation of bad method names lately that I used to see. However, I like to try to avoid un-necessary abbreviations. Be explicit and tell me what that method does. Such as “UpdateOpportunityStage” rather than “updateStage” — this is a very bad example in that if I’m working in a file like “OpportunityExtension” a method called “UpdateStage” should be obvious, however as an outsider coming into your org, how am I to know if you’re not updating some related object’s custom field stage? For just a few more keystrokes, you can have valuable clarity.
  2. Variable Names: more important, in my mind anyway, are the variable names that you use. Avoid abbreviations here like the plague as well. You’re not saving yourself much in the grand scheme of things, and to an outsider trying to learn the ins and outs of your code (and your business) an abbreviation can be a head-scratcher. For instance, if you have a product called Extra Widgets and you need to work with one in your code, call the variable extraWidget, not “ew” or exWg, etc. There are times when an abbreviation makes sense however, such as when everyone, and I mean everyone, refers to Extra Widgets as “EWs”, then perhaps saying “ew” is fine. However, if I’m in a rather large class file and that variable is instantiated way above the fold somewhere and I run across “ew” — wouldn’t it be a bit clearer if instead of having to figure out what “ew” was, its name told me right away: extraWidget. Again, clarity gets the nod.
  3. Spacing: Python introduced me to something that developers either love or hate. The used of whitespace. In Python, it can get annoying for newbies because indented code signifies your “blocks” — there aren’t curly braces or semi colons. This results in very readable code. It does however mean that many a new Python developer runs into issues at “compile time” because they used a tab in one place and 4 spaces in another. (Don’t get me started on the whole tabs vs. spaces thing…). I love white space and I tend to use insert carriage returns before I introduce larger chunks of logic flow. It separates your code into readable chunks of logic. Like Java, Apex is littered with curly braces and semi-colons galore, punctation that the mind just isn’t used to reading “naturally” — by adding whitespace between the different blocks of logic provides a natural separation and seems easier on the eyes.
  4. Comments: Its been said that good code comments itself, and while this is indeed true it doesn’t get you out of commenting code. I believe the real problem here however is the content of those comments. Of course good code comments itself, but it doesn’t tell you WHY its there or performing its duties in the given manner. It doesn’t tell you what was in the programmers head at the time it was written. Good code comments tell you WHY something was done, not necessarily WHAT it was doing. These types of comments can prove very valuable to any new programmers inheriting your code, or even to yourself when you have to revisit code you wrote months and sometimes even years ago. We’ve all had that moment when reviewing old code where we’ve said: “What the HELL was I thinking, why did I do it like THAT?” only to begin charging down the refactor path until you stumble across that little business rule you forgot about and realize: “Oh, THAT’s why I did it that way!” #BeenThereDoneThat
  5. Coding Shortcuts: I imagine I will catch proverbial hell from some folks on this and its really a matter of opinion (as all of this post is) but hear me out. Code “shortcuts” (like ternary operators) have their place in “oh-look-how-few-lines-of-code-I-took-to-write-this land, but they do NOTHING for readability for me. We’ve all seen them and I’d like to think I’m not the only one that sort of has to blink their eyes and read them twice:
    SomeVar var = (x == true) ? thisVar : thatVar;
    

    I can appreciate its simplicity and concise presentation, but I still prefer to read this:

    SomeVar var;
    if(x == true) {
        var = thisVar;
    } else {
        var = thatVar;
    }
    

    While this is quite a few more lines of code its VERY clear to a newbie programmer (or cranky old one) under which conditions the value of “var” will be set to either “thisVar” or “thatVar” Most programmers are used to reading the ternary so it’s not a huge deal, but I know for myself, I always have to re-read those conditions twice to be sure. These are somewhat similar to the whole “one liner if statement” where if you are only checking if a given condition is true, you can do so on one line and eliminate your curly braces etc. (It figures, the one time you can actually NOT use the curly braces, and I don’t prefer it…weird).

In closing — I’m set in my ways and wouldn’t expect anyone to conform to how *I* want things done. However, diva though I may be — I hope that some of these points would cause one to ponder, if only briefly, about the readability of ones code by outside sources. It won’t always be a seasoned vet, or someone who knows your business in and out that winds up reading your code. They’ll have enough to deal with coming up to speed on the ins, outs, and whys of your business, learning the local vernacular, etc. Therefore, making your code a little more legible can remove one less barrier to entry.  And with that, its back in the closet I go.

 

:wq!

Take a Break

Over the past 10 business days, I’ve been working heavily on a project for a client that is using Salesforce but my coding efforts have been nearly 100% focused on client side javascript. To be more specific, I’ve been living in the jQuery world for 10 days. Doing so has proven to be beneficial to me as a developer in several ways, and it caused me to reflect a bit on why I feel I really needed this breather:

  1. I’ve been living solely in Apex and Visualforce for two years now & I feel like I’ve lost a bit of ground on some of the things I used to do “pre-Salesforce”. Client side javascript was one of those things. It has been good to rekindle some of that front-end fire and exercise that skill set a bit. The old adage is true, “if you don’t use it, you lose it.”
  2. It revealed some features to me that I didn’t know about the platform. Specifically, the ability for the apex:actionStatus tag to call out to javascript using “onStart” and “onStop” events (perhaps a more technical post on this subject in the future is warranted). In this case, there were several re-renders happening over panels that need jQuery’s attention as well. Since these items may or may not have been part of the DOM on the initial page load, this wasn’t very straightforward. Furthermore the re-render actions were setting defaults from the server that needed to be overwritten by jQuery due to previous user actions, so after the re-render was complete, I needed to re-establish or re-evaluate the user inputs from before the re-render. Due to the project’s usage of the jQuery BlockUI plugin, I was able to tie into that plugin’s “hide” method and then execute the necessary jQuery to manipulate the newly rendered DOM elements. #Slick
  3. Sometimes you just need a break from status quo to refresh your mind. It opens you up to new techniques that living in a silo’d world may sometimes prevent you from picking up. In the end, taking these sideline breaks only strengthens your overall knowledge and that’s a good thing. #AlwaysBeLearning

I’ve still got plenty of jQuery time in front of me on this project so I’m looking forward to further honing that skill set and learning more about what is available to me on the platform side. Breaks are a good thing, but it will be good to get “home” again as well :)

 

:wq!

 

Wednesday Wrap Up — October 2014 Edition

Being fairly new to this “regular blogging” habit that I’m trying to form, I’ve decided that the first Wednesday of every month will be known as “Wrap Up Wednesday” here on sudovi.com.  What I plan to do is simply summarize everything that either influenced me, entertained me, or general buzz that interested me from the previous month. Some of it may be related directly to Salesforce but buyer beware — I’m a man of many interests so there may be some other things that sneak in from time to time. So without further delay, welcome to the first of hopefully many “Wednesday Wrap Ups!”

Personal Happenings:

  • Highlight of my year: I got to sing at Dreamforce! (Okay, i really will shut up about this…someday.)
  • I had a lightbulb moment
  • I reflected (perhaps out of place) on what I think makes a Salesforce MVP
  • Sarah Deutsch asked me to rewrite the lyrics to “All About That Bass” and she totally rocked it!
  • I smoked my first cigar and had my first Armagnac thanks to my new buddy Adam Daw. Armagnac — hell yes. Cigar — I’ve got much to learn…maybe @MichaelForce can help.

Dreamforce 2014:

  • The developer group over at Salesforce launched “Trailhead” and I’ve been enjoying watching the tweets come through as people complete the modules/challenges. I’ve not gotten very far myself, but intend to go front to back through all of the content. Some will be review but we can always use review. I’ve already referred a personal friend to it to get him up and going with Salesforce. I can’t wait to watch his progress & its a great way to started on the force.com platform.
  • Lightning Components were opened up to developers and it promises to be slick as hell. I’ve only been able to spend a few hours with it so far, but I believe it will change much of what a developer on the platform does in the future. Our jobs won’t change immediately, there will always be enough apex work to go around, but things will indeed change. Jeff Douglas has a great intro to lightning so check it out.
  • Process Builder seems to be getting quite a bit of attention as well and really will shake things up in admin land. Brian Kwong (aka SalesforceWizard) has several good entries regarding process builder. I’ve not had the chance to do much besides give it a glance at this point but I believe its open beta so it would behoove you to get on this now.
  • Salesforce released Wave and next generation analytics platform. To be honest, I was wowed by the demo at the keynote — but that’s as far as I took it. I can’t focus on everything and I’m scattered as it is :)
  • POODLE just doodled all over SSL. On October 14th google engineers released information regarding a flaw in the SSL 3.0 protocol. Salesforce announced they’ll be shutting down that protocol and mass hysteria ensued. Its all very confusing and hard to even tell if one will be affected by it. There is a link on stackexchange that goes into excruciating detail of what the problem is and further down there is a link that will help you figure out which services may have a problem with this, but for the impatient…I think the magic you are looking for upon test completion is in the configuration section of the results. You’re looking for support of TLS 1.0 at least.

Other tech related stuff:

  • Apple CEO Tim Cook comes out as gay. This shouldn’t matter, but sadly we still live in a world where people think this an issue of some sort.
  • Apple Yosemite was released — and I like it :)
  • The Django project added four new core team members. Congrats folks!
  • An Indiegogo project was launched to help Django provide first class support for third party templating engines. I personally prefer the tempting framework that Django provides out of the box, but this can only help…

There are many more items of tech interest that I am sure I am leaving out but these are the ones I am remembering. This month, perhaps I’ll start bookmarking these things…I just hope I can keep this habit up! For now…

 

:wq!

Request For Help

Me: Hello — My name is Ryan and I’m an introvert.

Others: “Hi, Ryan”

The first step is admitting it right? With Dreamforce 2014 just a few short days away I can already feel my anti-social self coming to the forefront. I’m generally very quiet unless we’ve shared the same social circle for some time. Last year for instance, I sat with my colleague (@KellyLeslie44) at the networking event for 15 minutes while I worked up enough nerve to approach two complete strangers and ask someone about the Google Glasses they were wearing. These sorts of situations always make me as nervous as I was when I was a sophomore band geek in high school asking a senior to homecoming (she said yes — as friends of course).

This year I feel I saw a number of improvements in my “social confidence” if you will. I released a song (I promise to shut up about it after this) to the Salesforce community that was met with a warm reception, and even appeared in a video for a different song with a rather prominent MVP figure in the Admin community. But that’s easy — that’s virtual. In the virtual world, its easy for a socially challenged person like me to come out of their shell. In person — and I don’t know why — its much more difficult for me.

So at Dreamforce ’14 I’m asking for your help. If you see me staring at my damn phone, or otherwise being an anti-social wallflower, publicly call me on it by sending me a tweet so the world knows that I’m not holding up my end of the bargain. A simple “Hey @lifewithryan — put down the damn phone and talk to someone” would suffice. Don’t let me get away with being anti-social. I’m not saying invite me into your conversations or anything like that (that would just be weird) but hold my a$$ accountable. Of course by inviting you to tweet it, I’m naturally still hiding behind the virtual curtain but this way, in case you’re like me, you don’t have to approach me and strike up a conversation if you’re not ready for such things (baby steps man, baby steps).

Of course, I’m going to make a conscious effort in being more social so this isn’t on you — its on me, I’m just asking for perhaps a little nudge if someone sees me avoiding interaction. If you are at all like me, let me know and I’ll do the same for you. Hope to see you at Dreamforce.

 

:wq!

Fun with the Wizard

Yeehaw!

About two weeks ago, Brian Kwong (@kwongeriffic) a.k.a “The Salesforce Wizard” (@SFDCWizard) contacted me about collaborating with him on a tongue-in-cheek parody of Kenny Rogers’ “The Gambler.” This song and video are related to his upcoming talk at Dreamforce 2014 in just a few short weeks. This morning over at “Wizard News”, Brian released the fruits of our labor upon the Salesforce community, complete with a blooper reel.

Brian already had a good portion of the lyrics written and with some help from Mark Ross (@markross__c) and myself, had the thing settled and ready to fly rather quickly. We didn’t get to practice the lyrics with the music until the day we recorded so it took us about a dozen attempts to get close enough for community consumption. I personally want to thank Brian for asking me to participate in such shenanigans — after all I loves me some shenanigans and tomfoolery. The fact that I got to hang with an MVP for couple hours was just the proverbial icing on the cake.

So head over to the site and check it out. I hope you enjoy watching it as much as we enjoyed creating it…and “we’re sorry!”

 

:wq!

Standard Page Layout Blackbox Magic in VF

As a developer, I’m often times very eager to jump in and start writing code. The Salesforce platform however has a “Clicks Not Code” methodology that I often overlook. Much of the time when a developer is asked to step in, the majority of the “Clicks Not Code” options have been exhausted. It’s no wonder then that I often forget that even though its time to start slinging code, there are number of prebuilt items that I can leverage. This morning, this bit me in the posterior for awhile.

I was working with a bit of legacy code that now required us to have different types of the same object, we’ll call this Object A for simplicity sake. We also have another custom object, Object B that has a lookup to Object A. However, Object B now also needed two more lookups to Object A in order to represent the other types (it was possible to have all three populated at the same time). So far so good. Object B -> Lookup Object A (Type 1), Object B -> Lookup Object A (Type 2), Object B -> Lookup Object A (Type 3).

Object A is represented in the UI using a custom VF page. Now normally, I’d be all to eager to build the VF page *completely* from scratch, field by field as that’s what I’ve been doing for 14 years. With Salesforce, its possible to leverage the prebuilt pieces of the object PageLayout using specific apex tags. In this case, the existing page was using <apex:detail> and <apex:relatedList/> tags to represent the basic details of the object and the Object B related list respectively. I had to add two more related lists to this page and have them conditionally rendered based on Object A’s type field.

The original Object B related list had several columns that my related list needed to duplicate, however no matter what I did I could not figure out how to add these columns to my related lists. As it turns out, the answer is simple. Since I was using the <apex:relatedList/> tag, all I had to do was edit Object A’s standard page layout, select my related lists, and add the columns there. This thought never even occurred to me because after all, from a coding stand point, I was using VisualForce, not the standard page layout, all the while forgetting that the builtin in tags use the default related list functionality from the page layout.

So, if you find yourself struggling in VisualForce code, don’t forget some of the black box magic that is taking place behind the scenes. Even though you may not be using the standard page layout, that standard functionality is still playing a role.

 

:wq!

 

Thats Why Admin’s Drink

EDIT: My kickstart to get this professionally going. Please consider helping out.

Reverb Nation (link to audio)

As a hobbyist musician — lets face no Grammy’s are heading my way anytime soon — I couldn’t resist writing a song about Salesforce. I’ve been particularly infatuated with the hash tag: #ThatsWhyAdminsDrink. So today, I bring to the incredible admin’s all throughout the Salesforce community their very own song based on the afore mentioned hashtag.

This comes with a caveat however, not only am I NOT a professional musician — I’m even MUCH LESS a professional sound engineer. I can do some very basic “stuff” with Garage Band, but I feel in order to do this right, I’d like to have this professionally recorded in a studio but someone who actually knows what they are doing. To that point, I’d also like to add some studio musicians to the mix because I need drums, bass, and a guitar player that can solo. I have a few connections that I can line this up with no doubt but it all takes time and money. Time I can deal with, but money, not so much. So this is me, writing a song for a community I’ve enjoyed being part of for over a year now, asking for a little help in making this something we can all point to and tell our friends: “That song is about me — and what I do everyday” :)  Please consider donating to my Kickstarter project in order to help me make this a real thing :)

For now, the very rough recording can be found on my Reverb Nation page (Dammit Andy).

I know its rough, but please let me know what you think in the comments.

 

:wq!

10 Things to Do When Salesforce is Down

1. Stand up and stretch, enjoy the feeling as the blood rushes back into your extremities.
2. Get a drink — I recommend water but a caffeinated beverage works too.
3. Drop in a a workmate, ask them how there day is going.
4. Do you have the use the bathroom? Now would be a good time
5. Check Twitter — see what @reidcarlberg, @kwongeriffic, @benioff, hell even @benioffshoes is up to.
6. Check email, respond to that message you’ve been avoiding.
7. Clean your work area.
8. Smoke ’em if ya got ’em!
9. Breathe deeply.
10. Chill the heck out — this stuff happens and you’re not the only one “trying to run their business”
11. BONUS: lighten up and enjoy the brief break for cryin’ out loud, it will be back.

2013 Brings a New Job

It’s been far too long since I last had anything that I deemed “useful” to say. I find myself opting to not write anything whatsoever if I feel its something that doesn’t provide some perceived value. 2013 was full of those moments. I’ve never been one of those “confident” techies who can just spout off amongst a group of my peers. I’d rather sit back, listen and learn something, but on the back side of that is — “what if I really am not as good or as smart as I think I am?” (or insert other “I blame my childhood experience” related item here).

In the coming year and hope to be more vocal than I have been in the past. Part of that will be breaking out of my introvert’s shell (something that seems to only exist in my professional life — ask most who know me, I don’t think “introvert” is the word they’d use to describe me). I hope to use this blog as a tool to help me do so.

With that said, 2013 brought with it a job change in mid-May. I left my previous employer of 10-years after much deliberation. It was like leaving family, but I had gone as far as I think I was going to go with the company and the opportunities for growth that existed didn’t really get me excited so it was time. The only thing that would have gotten me to stay was being offered a full on R&D position where I get to learn new technologies and present/report back — maybe even fly a few projects off of. However, I couldn’t in good conscience have asked for such a thing. Having a family and real-world responsibilities meant I couldn’t “just leave” so I began my first active search in a decade.

As luck would have it, I was approached by a former co-worker who had left to start his own consulting firm a few years back. It couldn’t have been timed more perfectly and I am now a full-time Certified Salesforce Developer at Radial Web. Its definitely a different world. Since the majority of the projects I deal with are internal and not “customer facing” deliverables, I don’t feel as much pressure as I did previously and for the first time in 10 years — I enjoyed a Holiday Season without a single work-related issue to attend to.

As far as the “work” itself goes what *really* attracted me to this job wasn’t the coding aspect…it was the opportunity to grow business/leadership skills. I’d always been the “personable” programmer, but rarely did it leave the “programmer” part at the keyboard. This opportunity provides me with the chance of helping grow a team, an opportunity to hopefully lead — not just supervise other coders –but truly lead a thought process and culture within a company. I keep telling people that I don’t want to be the 65-year old programmer. That gives me approximately 26 years to leave that behind… :)

:wq!

It’s the small stuff…

 

I know, I know! It’s been a very long time — I tell myself its because I only speak when I have something to say.  Whatever gets you by right?

Anyway, over the past few weeks (very much off and on, more off than on) I’ve been working on an algorithm for building a schedule of teams for a league manager.  What started out as something that I thought should have been very simple turned out to be much more complicated that I’d originally thought.  I remember thinking “2 hours tops” — ever have one of those moments when you realize that you clearly weren’t thinking when you opened your big fat mouth?

Sure, some of you could probably write this in your sleep, but I did some googling, asked around a bit etc, and as it turns out, its not as easy as you might think.  (Just google for league scheduling algorithm — better yet — let me google that for you).  I think you’ll find that there are more lines of code than one would think and a number of people attempting to roll their own that have come running for help.

I found several good examples, but with many of them, the code wasn’t very reader-friendly.  I found myself down so many dead ends and just about the time I thought “this is it, I’ve got it” I’d fall flat on my face again.

I walked away.  (I did it on paper which turned out to pretty easy and how I came up with an algorithm that I was (and still am) sure I could use).  However it bothered the living daylights out of me that I couldn’t solve the problem. I eventually left my afore mentioned algorithm behind and though I believe it’d be way more efficient and someday plan to figure out how to get it working, in the interest of getting something done — one of my mantras — I moved forward with an approach that I was making progress with.  At long last, I had a schedule builder that I can use for the bocce league that I’ve been made captain of recently.

For those of you looking for code — I’m not going to show it for numerous reasons:

  1. Part of me still believes this should have been much simpler and frankly I’m embarrassed
  2. This sounds like it could be someone’s homework assignment and I’m not about to be giving any answers
  3. I may wind up using it in some actual software I’m working on

Overall, it comes down to be remembering to go back to the basics:

  1. Start small, solve only small problems.  If you feel its a big problem, break it down into its smallest chunks and solve each chunk as its own problem.
  2. Use pseudo-code — my oh my when did I ever stop pseudo-coding things?  So very helpful to break down the problem domain.  (Note to self, is there a possible software solution here….hmmmm)
  3. Comment the living crap out of your code.  When you walk away for a bit or get interrupted, you’ll be thankful.  Many people say good code comments itself.  I say “nay nay.” When you are solving an issue you’ve never solved before and had to google a few things, you wind up writing obscure bits of code or syntax that you’ll no doubt forget about and forget what purpose it served or what functionality it provided.   Comments are still a very good thing.  Anyone telling you different is plain wrong.
  4. Don’t be afraid to start over or delete code.
  5. Don’t be afraid to write something procedurally, at least at first.  My solution was very much done procedurally.  It was not OO or functional.  After all, an algorithm is a recipe.  A recipe is very procedural. Writing something procedural to solve a problem helped me a great deal in this case and provided me with a clearer understanding of the problem at hand and its solution.

Again, this is probably a very simple problem for some of you.  For some reason, the solution eluded me for much longer that I’d like to admit.  There is still one strange kink that I have to wrap a try/except block around and thats on my list to work out, (as well as providing support for bye-weeks) but at last its refreshing to see a schedule actually being built.

I’m really curious to see if anyone else has worked on this problem, or if anyone else would like to try working it out for themselves in their language of choice and them come back and provide their insight/feedback etc.  I don’t expect you to show code since I didn’t even do that myself, but I’d love to hear your opinion on how easy/hard you found this to be.  In the end, I fully expect to be an idiot here and its something very simple that just eluded me and if thats the case, I’m fine with it — sorta.  But I’d love to find out if anyone else underestimated the issue.  So if you wanna give it a try, here are the rules I had to work with:

  1. X number of teams over N  number of weeks.
  2. In my league, each team plays each other only once.  (This was the sticking point here, we had 8 teams, they wanted an 8-week season which means there has to be a bye-week, or you just play a 7-week season.  Since they wanted 8 weeks, I have to add bye support in there.  I’m still working on that.  That being said, if you have 16 teams, you need at least a 15-week season, or 16 weeks and everyone has one bye week.  Or you can have 8 teams, play each other twice for 14 weeks with two bye’s, etc which is something else I haven’t worked out yet but plan on doing).

There are a ton of edge cases, so let’s stick with the following:  8 teams, 7-weeks, everyone plays each-other once.  Man…even saying it again makes it sound so simple but yet I found it so much more difficult that I expected.  Wasn’t the hardest code I’ve ever had to come up with by a long shot, but was much more painful that I thought it should have been.  Any takers?

 

:wq!