Ruby Procs And Lambdas (And The Difference Between Them)

LambdaAs you know, I am a big believer in knowing the basics. I find it is especially valuable to go back to the fundamentals of whatever skill you're trying to master periodically, as you gain more experience. Somehow you're always able to extract something valuable from the experience due to the extra insight you've acquired along the way. Recently I've been looking more closely at some Ruby concepts that I may have glossed over when I was learning the language initially, so I will likely be writing about this in some of my upcoming posts. I thought I would begin with one of the most powerful features of Ruby – procs (and lambdas :)).

What's So Good About Procs?

You know how everything in Ruby is an object, well, as it turns out that's not quite true. Ruby blocks are not objects! We can discuss the implications of that, but let's refrain, accept it as fact and move on. So, blocks are not objects, but you can turn them into objects without too much trouble. We do this by wrapping our block in an instance of the Proc class (more on this shortly). This is really great since it turns our block into a first class function, which in turn allows Ruby to support closures and once a language has closures, you can do all sorts of interesting things like making use of various functional concepts. That however is a story for another time, before we dive deep into those areas, let us really understand how Procs work.

Why I Love Reading Other People’s Code And You Should Too

HateIt occurs to me, that many programmers hate reading code – c'mon admit it. Just about everyone loves writing code – writing code is fun. Reading code, on the other hand, is hard work. Not only is it hard work, it is boring, cause let's face it, any code not written by you just sucks (oh we don't say it, but we're all thinking it). Even your own code begins to look increasingly sucky mere hours after you've finished writing it and the longer you leave it the suckier it seems. So, why should you waste hours looking at other people's crappy code when you can be spending this time writing awesome code of your own? Weren't we just over this; give it a couple of hours and then come back and see if your code still looks awesome. You're never going to become a master of your craft if you don't absorb the knowledge of the masters that came before you. One way to do that is to find a master in person and get them to teach you everything they know. Is this possible – certainly, is it probable – not so much, you'd have to be extremely lucky. You don't really need luck though, we're fortunate to be in a profession where the knowledge and skill of all the masters is right there for us to absorb, embedded in the code they have written. All you have to do is read it, sure it might take you a bit longer without someone sitting there explaining it to you, but it's eminently possible. To put it in perspective, try becoming a great carpenter just by looking at a bunch of well constructed furniture.

Closures – A Simple Explanation (Using Ruby)

ClosureThere are a great many decent developers out there who don't know what a closure is. I don't really have any concrete stats on this matter, it is simply an intuitive assessment based on experience. But, you know what – that's fair enough, considering that the most popular languages that are in use right now don't support closures (Java, C++). When the language you use day in day out doesn't support a concept, that concept is not going to be high on your agenda; infact you may not even be aware of it. And yes, I agree, good developers will know several (or perhaps many) different languages and there are plenty out there that do support closures – you're bound to stumble across one at some point. Which just goes to show that when most developers learn new programming languages, they go about it completely the wrong way and so when you hear someone say they know a dozen languages, they are likely overstating the situation by quite a margin. But, I'll leave that discussion for another time – today it is all about closures.

Sort Files Like A Master With The Linux Sort Command (Bash)

SortIf you do your development work in Linux, there are certain commands that you owe it to yourself to master fully. There are a number of these with the main ones being grep, find and sort. Just about everyone has at least a passing familiarity with these commands, but with most people the knowledge is superficial, they don't even realise how powerful those commands can be. So, if you really put in the effort to master them, not only will you make your own life much easier, but you will also be able to impress all you friends with your elite Linux skills when you pair with them :). I will cover grep and find (as well as other valuable commands) in subsequent posts – here we will concentrate on sort

Note: I am using bash, so your mileage might vary if you're using a different shell.

Sorting is a fundamental task when it comes to programming, if you have a decent knowledge of various sorting algorithms, their advantages and disadvantages, you will be a better software developer for it. However, often enough you just don't need to draw on this deeper knowledge. Whether you're answering an interview question about sorting or simply need to quickly sort some data in you day to day work – the Linux sort command is your friend.

What Every Developer Should Know About URLs

I have recently written about the value of fundamentals in software development. I am still firmly of the opinion that you need to have your fundamentals down solid, if you want to be a decent developer. However, several people made a valid point in response to that post, in that it is often difficult to know what the fundamentals actually are (be they macro or micro level). So, I thought it would be a good idea to do an ongoing series of posts on some of the things that I consider to be fundamental – this post is the first instalment.

Being a developer this day and age, it would be almost impossible for you to avoid doing some kind of web-related work at some point in your career. That means you will inevitably have to deal with URLs at one time or another. We all know what URLs are about, but there is a difference between knowing URLs like a user and knowing them like a developer should know them.

Executing Multiple Commands – A Bash Productivity Tip

MultipleI love shell productivity hacks. I believe that if you work in a Linux environment, you owe it to yourself to become as good as you can be at working with your shell of choice (e.g. bash). You see, most people who have worked with Linux for any length of time have some level of skill with the shell, that level is usually mediocre at best. But, you do meet the occasional person who wows you with what they can accomplish and I will tell you right now that their skill does not come from superior knowledge (or at least not fully from superior knowledge). It is all about maximizing the effect of the knowledge you do have, finding little tricks and hacks that will save you, potentially less than a second, every time you perform a particular action. Thing is, some actions you might do hundreds of times per day, so those seconds really start to add up, especially once you have accumulated dozens of these hacks. Anyway, here is one such tip.

Merging Ruby Hashes And Bang Method Usage

MergeThe other day something curious happened that made me question how I use bang methods (and their non-bang cousins). Here is how I normally look at using bang methods in Ruby. Always use the non-bang version, unless you have a really, really good reason not to. It just seems somehow safer this way, like when you're passing an object (String, Array etc.) around as a parameter, don't modify the parameter itself unless that is exactly the behaviour you're looking for. Use methods that don't modify the original object, but rather work on a copy, and then return the copy to the calling code. Maybe I am being too asinine about this, do come and let me know if I am :). Regardless, I have trained myself to avoid bang methods unless I really need them, but a few days ago I needed to merge some hashes.

You see, I had a file full of smaller hashes (serialized) that I wanted to read in and merge into one big hash. As usual, I tried using the non-bang version of the merge method and it just crawled. Let's recreate this code:

main_hash = {}
time = Benchmark.realtime do
  (1..10000).each do |number|
    simple_hash = {}
    simple_hash[number.to_s] = number
    main_hash = main_hash.merge(simple_hash)
  end
end
puts "Time elapsed #{time} seconds"
puts "Main hash key count: #{main_hash.keys.count}"

This produces:

A “FizzBuzz” Faux Pas

fizzA little while ago while writing this post, I came across the post by Jeff Atwood where he talks about the FizzBuzz test (originally found here). I remember seeing that post for the first time a couple of years ago and thinking that I would be a little insulted if someone asked me to write something that trivial in an interview. Seeing it again the other day I realized that my feelings hadn't changed. It IS an insulting question. Sure you may quickly weed out complete incompetents by asking it, by you will also alienate just about every competent developer. There is really no reason to ask a question that simple. You might as well ask something more complex, that could really test a programmer's skills. The incompetent will still have no chance, and you won't make the decent developers feel like you're making fun of them. If you can't think of any interesting programming questions to ask (and you don't like my quine question :)), I will try and cover a few decent, straight forward coding questions at some point in the future. But, that's not what this post is about.

Serializing (And Deserializing) Objects With Ruby

Serialization is one of those things you can easily do without until all of a sudden you really need it one day. That's pretty much how it went with me. I was happily using and learning Ruby for months before I ever ran into a situation where serializing a few objects really would have made my life easier. Even then I avoided looking into it, you can very easily convert the important data from an object into a string and write that out to a file. Then when you need to, you just read the file, parse the string and recreate the object, what could be simpler? Of course, it could be much simpler indeed, especially when you're dealing with a deep hierarchy of objects. I think being weaned on languages like Java, you come to expect operations like serialization to be non-trivial. Don't get me wrong, it is not really difficult in Java, but neither is it simple and if you want your serialized object to be human-readable, then you're into 3rd party library land and things can get easier or harder depending on your needs. Suffice to say, bad experiences in the past don't fill you with a lot of enthusiasm for the future.

Ruby Access Control – Are Private And Protected Methods Only A Guideline?

ProtectA few days ago Chad Fowler ran the following quick quiz on Twitter:

Ruby quiz: in 140 chrs or less, why doesn't this work: class Y; def a;
self.x end; private; def x; puts "hi" end end; Y.new.a

Here is the formatted version:

class Y
  def a
    self.x
  end
  private
  def x
    puts "hi"
  end
end
 
Y.new.a

Running this produces the following error:

a.rb:3:in `a': private method `x' called for #<Y:0x7f819a82d548> (NoMethodError)
    from a.rb:11

I wasn't immediately able to figure out what was wrong with this code and since access control is one of those fundamental things that you should know, if you want to be a decent Ruby developer, I decided to dig a little further to figure it out. Here is the scoop.

Private, Protected and Public – Ruby Method Visibility

The concept of private, protected and public methods in Ruby is somewhat different than it is in languages like Java (well, not so much public, that's very similar :)). In Java if a method is declared private, it can only be accessed from other methods in the same class. When a method is declared protected it can be accessed by other classes in the same package as well as by subclasses of its class in a different package. When a method is public it is – of course – always visible to everyone. So, in essence with Java, these keywords protect the various members from access by classes, depending on where these classes are in the inheritance/package hierarchy.