Archive for July, 2008

Job Offer Dissection

Thursday, July 31st, 2008

I used to do these when I didn’t have a job, and since then I’ve been looking a lot less (read: not at all) for a new job. This, however, was accidentally clicked on in Apple Mail and I was tempted to dissect yet another one.

From: ryanbrogan@gmail.com

This is what made me cringe the most. If you’re a recruiter sending out recruitment emails, why do it from a gmail address? Why not use your own?

One of my top clients and an incredible place to work…

Who? It helps to list names. Names attract people. If I told you I was going to buy you a beer you’d get all excited. Then I would reveal it would be a Fosters, and you wouldn’t be so excited.

secure two developers for staff positions paying 75-95k.

With / without tax? Numbers are great, but more information is definitely needed here.

Email me @ ryan [at] magnetagency.net

Ah! There it is!

or ryanbrogan [at] gmail.com

No really?

1000.00 referral fee if someone you refer gets the position.

Rupees? Zimbabwean Dollars? Kroner? Helps to specify a currency… but I guess American is inferred. Also, “fee”? Do we owe you money if we refer our friends to you?

  We know you’d send your pals for free, but that’s how we roll :)

Ah, a smiley face. It makes me feel all warm and fuzzy. Also, respect goes out to the use of non-professional language here, makes it feel much better.

We have an aggressive product list comprised of social, personalization, user-generated, and content publishing features planned for the site

“Aggressive product list”? What are we talking here? A few robberies with a weapon? Rape? Murder? Genocidal maniac?

and we’re looking for a self-motivated developer to join the team.

The team should motivate the developer, but it does help to be self-motivated too. Each member of the team should feed off each other’s energy.

If you’re interested in working in a fast-paced,

Running makes me sweaty. How fast are we talking?

energetic environment

Pepsi Max and a proper sleep cycle gives me all the energy I need

come work for us.

Rather not, I hear the commute from here to there is about 22 hours!

Core Requirements:

As compared to the other kind of requirements?

* You’re passionate about the craft of software engineering and love building cool Web applications

So, say, an aspiring Trolley Pusher wouldn’t be the right kind of person for this job then?

* You’re familiar with Test/Behavior Driven Development and agile software development

We spent long nights together in an orgy of code. There were files flying all over the place! A few commits took place, but nothing serious.

* You have production Ruby on Rail experience

Ruby’s going monorail now, huh?

including deployment

Inferred from last statement

with Mongrel

ditto

* You’re comfortable with semantic XHTML and CSS (not necessarily design)

Uh oh, -1 point for chucking in “semantic” in there. Big words make people sad. “Well-structured” is what I would put there.

* You’re familiar with Javascript and AJAX

I have nothing witty to say about this.

* Ongoing application development

Well, given that the position seems to be a Software Engineer-like position, this is pretty much a given. All application development is “ongoing”

* Production support and ticket management

Ah, so the position is now more of a Software Engineer meet Tech Support meet Project Manager position now? Cool. Probably a bit overwhelming for one person (we have this in three separate roles @ NetFox)

* Deployment management

Easy enough with Capistrano, which most Ruby on Rails developers worth their salt should know.

Overall, a fairly good job advertisement. Still struggling to come up with a reason for posting from Gmail, but I’m sure there’s a fairly good one behind it. Thanks for not using buzzwords (apart from the iffy “semantic”)! It takes me so long to pick them all out and decipher them… I once saw “increases business continuity” on a website and I’m still trying to figure out what it means.

Stop Being So Self-Centered!

Tuesday, July 29th, 2008

I’ve seen so many examples of people being self-centered in their code, always calling their methods on self when they don’t need to!

self is a handy reference to the current object (or class) depending on how the method is defined. In a class that inherits from ActiveRecord for example, calling self before defining a method will define that method on that class, rather than the objects of that class. Once inside of the method, you are free to go about as you will; Ruby will know what you mean when you call other methods inside that method.

A prime example would be this self-centered piece of code:

class Forum < ActiveRecord::Base
  acts_as_tree
  
  def to_s
    self.title
  end
  
  def self.find_all_without_parent
    self.find_all_by_parent_id(nil)
  end
  
  def root
    self.parent.nil? ? self : self.parent
  end
  
end

These are a few methods with both good and bad examples of using self.

We'll start with #tos. This method is defined by typing def tos, which tells ruby we want to define a method called "to_s" on all objects of the Forum class. Inside the method however, we have a bad-case of self-centering, by calling self where it's not needed. Ruby already knows that we're operating with an object derived from the forum class, and calling self will only return the same object! So why do we do it here? We can remove the superfluous self call, and the method will still work.

Our next method is self.findallwithout_parent. The self. prefix to the method tells Ruby that we want to define this method on the Forum class itself, rather than a derived object from the class. Inside the method again we have a bad case of self-centering! Ruby already knows we're operating with the Forum class, and calling self will only return the Forum class once more. Again we can remove the superfluous self call and the method will still work.

In both of these examples, you could've called self on self and then the method multiple times: self.self.title or even self.self.self.self.self.title, but that's just going a bit overboard!

In the last method is two incorrect usages of self, and one correct use of self. The method is #root. The method defines a one-lined if statement by calling a method (self.parent.nil?) which will return either true or false. The next character is a space followed by a ?, which indicates to ruby anything after this is what we want executed when self.parent.nil? returns true. Here we just call self, and this is the good use of self. The #root method is attempting to find the root element for the tree heirachy of the forums, if the forum object we're calling root does not have a parent, we want it to return itself as it is the highest level of the forum structure. The next character in the code is a colon (:), which tells Ruby what we want to do if self.parent.nil? returns false. Here we've called self.parent, which again is a superflous call to the self object. We only need to call parent because Ruby already knows which context we are referring to! The final superfluous self call is the self.parent.nil? from where our one-lined if statement originated.

I hope you've enjoyed this little tidbit, and please stop being so self-centered.

UPDATE: RSL has posted an easier way than parent.nil? ? self : parent as the first comment. The code is now simply:

def root
  parent || self
end

UPDATE #2: The root method was still broken as I realised this morning as I tampered with the tests. The method is supposed to get the highest forum in a string of forums. This works perfectly for 2-level-deep forums, but not for 3-level-deep. The third-level element would've returned the second-level element rather than the first. The revised code is now:

  def root
    parent.nil? ? self : (parent.root == parent ? parent : parent.root)
  end

Rescue Correctly!

Monday, July 28th, 2008

Too many times I’ve seen people being over-zealous in rescuing their exceptions. They try doing something like this:

def show
  @forum = Forum.find(params[:id])
  rescue Exception
   flash[:notice] = 'The forum you were looking for does not exist'
end

Which will work when it can’t find a forum, and also when you have a typo. Exception the ancestor class of all other exceptions, and so every exception will trigger this rescue. Try making the code look like this:

def show
  @forum = Forum.find(params[:id)
  rescue Exception
    flash[:notice] = 'The forum you were looking for does not exist'
end

and you’ll wonder why a forum is telling you it doesn’t exist when it obviously does! The easiest way to fix this is to rescue correctly. By rescuing correctly, you prevent hours of potential headaches and your code becomes clearer to what it’s doing. In this example, when a forum object can’t be found it will raise the ActiveRecord::RecordNotFound exception, so this is what you should rescue.

def show
  @forum = Forum.find(params[:id])
  rescue ActiveRecord::RecordNotFound
    flash[:notice] = 'The forum you were looking for does not exist'
end

Another situation is when you’re using #save!. This “destructive” version of #save will raise an ActiveRecord::RecordInvalid or ActiveRecord::RecordNotSaved, depending on the kind of validations you have on your model. I use it here in this example:

def create
  @topic = @forum.topics.build(params[:topic])
  @post = @topic.posts.build(params[:post])
  @topic.save!
  flash[:notice] = 'Topic has been successfully created'
  rescue ActiveRecord::RecordNotSaved, ActiveRecord::RecordInvalid
    flash[:notice] = 'Topic could not be created'
  ensure
    redirect_to forum_topics_path(@forum)
end

I’ve actually specified two arguments to the rescue method here, the first is ActiveRecord::RecordNotSaved, and the next is ActiveRecord::RecordInvalid. The rescue method uses the splat operator (*), so it can take as many arguments as you can throw at it. I’ve also used another method here ensure. No matter how many exceptions get thrown, the code after the ensure statement will always be ran.

The final thing I would like to cover is rescuing two exceptions, but doing two different things.

def create
  @topic = @forum.topics.build(params[:topic])
  @post = @topic.posts.build(params[:post])
  @topic.save!
  flash[:notice] = 'Topic has been successfully created'
  rescue ActiveRecord::RecordNotSaved
    flash[:notice] = 'Topic could not be created, the record could not be saved'
  rescue ActiveRecord::RecordInvalid
    flash[:notice] = 'Topic could not be created, the record is invalid'
  ensure
    redirect_to forum_topics_path(@forum)
end

What A Weekend!

Friday, July 25th, 2008

And it hasn’t even begun!

Here I sit on a Friday night, on my bed with two quilts over the lower-half of my body. Sitting by the open window (yes, open. Even though it’s winter and 7.7 celcius outside) on my bed with my laptop on top of the quilts. My mum’s boyfriend’s son sits on the only chair in the room, using UbĂ«rComputer and playing Spore Creature Creator, creating a dinosaur like creature. I feel relaxed, probably due to me getting off work a bit earlier than usual because the internet was balls (dialup had better ping times), and I know that there’s going to be a lot of stuff to do on the weekend.

Tomorrow I’m going to be attending AVCon, not because I like dressing up in a Sailor Moon costume (not that I’m going to of course), I just want to see what all the fuss is about. Two of my friends (Brenton and James) have both recommended in one way or another that I go, so I’m going. Hopefully I’ll enjoy myself, but it is an anime andvideogames conference, and I’m not all that in to anime…

I’ve been tasked (is this the correct word?) to host Railscamp #4! I have an idea for a venue and I’m going to check it out on Sunday. Hopefully if all goes according to plan there should be a formal announcement soonish. Price and what not is not worked out yet, but I have a good idea and I’m not going to tell you! I’ll have a better idea Sunday night, if I can be bothered blogging about it.

See you on the other side!

EDIT: I didn’t go to AvCon (thanks for answering my calls James!), instead I scoped out the venue for Railscamp #4, went cruising with Devastator in the epic quest for computer parts and generally lazed about like all decent people [should] do on a weekend.

Faking It

Monday, July 14th, 2008

Today I was doing the one thing I truly, truly love doing and that’s complaining about writing RSpec tests. I came across a doozy of a problem involving RSpec testing and faking subdomains. Here’s a stripped down version of what I did:

def login_as(user)
  session["user"] = users(user).id
  request.host = User.find(session["user"]).company.domain + ".example.com"
end

Just pop that into your spec/spechelper.rb and then you can use loginas(:user) which will find the fixture with the name of “user” and then go from there to setting your faked host as being from, for example, blah.example.com.

Pretty simple, shame Google didn’t turn up any relevant results without me having to dig deeper than usual.

Empty Wallet Treatment

Sunday, July 6th, 2008

Thanks to the guys at NetFox (Yuji or Adam) for the name for this post.

Tomorrow I go to the dentist to have empty wallet (read: root canal) treatment (hereafter referred to as EWT). My tooth that broke at Railscamp has a serious bout of decay in it no thanks to me not caring for my teeth as I really should have, for quite too long. Consider this a warning to all the readers of this blog to look after your teeth. It’s going to cost me a fair bit (thankfully I save money, rather than spend), and thanks to a complete lack of Dental insurance I’ll be paying through the nose (or is that the mouth?). I am not in any way looking foward to the needles (notice the plural!) that are going to be going into my gum tomorrow morning. The best part is that a client is coming in tomorrow at 10:30 and I’m one of the people working on their project, so I’ll be [attempting to] speak with them. Perhaps I could type and get the text-to-speech voice on the MBP to read it out, or something.

Look after your teeth, please. You are not invincible, and neither am I.