Plough => Ruby Journey through ruby

Ruby Hacking Guide

I got hold of an out-of-date Ruby Hacking Guide and it looks very interesting. Therefore, in order to improve my understanding of Ruby internals, I have decided to spend time in reading it and the writing posts about it. The entire book can be downloaded in the form of HTML pages and might not make sense since some of it has been machine translated.

I hope my efforts are useful for anyone willing to venture into Ruby Internals.

Method default arguments and passing nil value

This is something very trivial and I kind of observed it whilst programming couple of weeks ago. For example, you had a method like this:

  class SomeClass
    def some_method(some_argument = '')
      raise ArgumentError unless some_argument
    end
  end

Now, I was under the impression that if I passed in a nil into this method, for some reason some_argument will still have the default value(‘’) as opposed to the nil value passed in but default arguments come into play when no value is passed in for the method arguments. But I was passing in nil which is an instance of NilClass and therefore some_argument gets assigned the nil value and an exception is raised.

Convert Array to Hash mystery

It is always easy to find solutions on Google but the real fun is in finding out how a bit of code works. It just helps you understand much more about the language and how it behaves. Converting an array to hash is easy. Just use this piece of code that I found on google:

  some_array = [1,2,3]
  some_hash = Hash[*(some_array.collect{|v| [v,v]}.flatten)] # yields {1=>1, 2=>2, 3=>3}

Few people have asked the question behind this conversion and I just decided to break it apart and tackle it bit by bit. Our objective, again, is to convert an array to a hash. Hash’s ruby documenation tells us that a new Hash object can be created by using even number of arguments. Something similar to the following code:

  some_hash = Hash[1,1,2,2,3,3] # This creates a hash object similar to this {1=>1, 2=>2, 3=>3}

All we need to do now is convert our some_array (defined in the first code snippet) and convert it into [1,1,2,2,3,3].

It’s simple really. We take the some_array and convert it into an array’s or array like this:

  some_array = [1,2,3]
  some_array.collect{|v| [v, v]} # will yield [[1,1], [2,2], [3,3]]

Now to convert it into [1,1,2,2,3,3] we just need to flatten this array of arrays like this:

  some_array = [1,2,3]
  some_array.collect{|v| [v, v]}.flatten # will yield [1,1,2,2,3,3]

Now, all we need to do is use the splat (*) unary operator. The splat operator expands the supplied array into individual arguments which is what we need to convert array into a hash. You could also achieve the same with the following snippet:

  some_array = [1,2,3]
  some_hash = Hash[*(some_array+some_array).sort] # yields {1=>1, 2=>2, 3=>3}

I hope you can work that out yourself. I hope this little discussion helped you.

Paperclip and rescue

Reading Open Source Code is probably the best way of learning new ways. Paperclip is an amazing file upload tool by brilliant guys at Thoughtbot. And yesterday, while going through their code I realised that rescue can be used as a statement modifier. For example, consider this block of code below:

  type = (self.path.match(/\.(\w+)$/)[1] rescue "octet-stream").downcase

What do you think happens here? Its quite simple really. If the first statement (the match bit) raises and exception the second statement is executed instead.

Another way to write this would be:

  begin
    type = (self.path.match(/\.(\w+)$/)[1]).downcase
  rescue
    "octet-stream"
  end

Install pg and mysql gems

This is not entirely realted to ruby but if you ever program with ruby you will find yourself using pg and mysql gems and the issue is how exactly do I install them. This mini-post (rather tumble) is just to make a note of this. Run the following in Teerminal.

PostgreSql

  export PATH=/usr/local/pgsql/bin:${PATH}
  gem install pg

MySql

  export PATH=/usr/local/mysql/bin:${PATH}
  gem install mysql

Also, please note that you should have postgres and mysql installed on your machine.