Ruby for Rails by David Black is a fun read that takes concentration but repays it with little epiphanies that explain syntax and language features that you had previously taken for granted.
The book aims to “help Rails developers achieve Ruby mastery”. The coverage of Ruby features is not complete and there are some concepts missed that I would have liked to have read more about (eg, how do instance variables work under the hood?). There are also a number of introductory chapters on Ruby and Rails and some chapters devoted to a sample Rails project (R4RMusic) which I flicked through but didn’t add much value for me (they are also a little dated). By far, the most interesting parts of the book for me were on the Ruby type system, ‘self’ in various situations and how method look up works with modules and inheritance.
An area of Ruby that I had not previously explored was adding singleton methods to instances (like what you can do in Javascript). Eg,
o = Object.new def o.say_hi p "hi" end >> o.say_hi "hi"
or alternatively
o = Object.new class << o def say_hi p "hi" end end
Now, the interesting thing is that this is the basis for the whole class system in Ruby!
Classes are just a special type of object, and when you add class methods, you are really adding singleton instance methods to the class object for the type.
Ie, when you do something like:
class Cars def self.find_all ... end
You are actually creating a new object, of type Class which has a singleton method called 'find_all'. 'self' in the code above is the Class object, so def self.xxx is adding a singleton method to it.
This also explains the alternative syntax for adding class methods:
class Cars class << self def find_all ... end end
The same thing could be done by saying:
Cars = Class.new Cars.instance_eval { def find_all; ... end; }
In Ruby, the type and class system is not very different from the normal objects you work with every day. I find this really quite cute and internally consistent.
The way the method search path works in ruby was also nicely explained in the book. Basically, finding a method starts at the top of the list below and stops as soon as a method with a matching name is found (ie, that responds to the message sent to the object):
- Singleton methods on the object
- Methods defined by the object's class
- Methods defined by modules mixed in to the class
- Methods defined by parent class
- Methods defined by modules mixed into parent class
- Repeat checking parents until get to Object
- Methods defined on Object
- Methods defined on Kernel (module mixed into Object)
This also explains why you can always call methods like 'p' from anywhere. They are coming from Kernel which is mixed in at the top of the inheritance tree for your object. Another case of internal consistency - there's no 'special' mechanism for these seeming globals.
Overall, I enjoyed the book and would recommend anyone having a read who has worked with Ruby and Rails but would like to dig a bit deeper.
Dave Bolton
James, I really enjoyed this book as well. I highlighted a lot of it, but I really should have digitised my notes like you have. Good job!