Learn Ruby in 24 hours
Continuing live coverage of my attempt to learn Ruby in a day. Well the day had only 53 minutes left when I started this post. Thus the project name is here by changed to learn ruby in 24 hours out of necessity. By the way, is there a book by that title? What I am reading though is Mr Neighbourly’s Humble Little Ruby Book.
Implicit Block Usage.
This is where I got stuck at the previous step, that bit of code reminded me of the nightmares that I had while learning java threading nearly half a lifetime ago. So let’s skip over this bit. As far as I am concerned implicit blocks exist only for the explicit purpose of creating unreadable and unmanageable code.
Classes and Objects
Here is a short and sweet definition of an empty class:
class MyClass < Object end
Want to know if obj is an instance of some class? then obj.instance_of? someclass ought to do the trick
In both Java and Ruby, Object is at the root of all (evil). But while Java has what it calls primitives, Ruby does not, everything in Ruby is an object.
The constructor is always named ‘initialize’ and instance variables are always referenced by using an @ sign. Which means @ is the equivelent of ‘this.’ in java and ‘this->’ in PHP. A bit of quirk is that when calling another member method, you write it as self.other_method instead of @other_method. self. No prizes for guessing that self is the current object aka this.
In order to encourage bad programming, Ruby allows you to override methods in classes without extending that class. Just redefine the existing class and add a new method or replace an existing one.
dumb code here
By default all instance variables are private. Getters and setters like in Java Beans. A getter would look like:
on the other hand a setter would look like the following and would give a small whiff of operator overloading in C++
@param = value
But you really want your instance variables to be public you can make it so with the
attr_writer :param1, :param2
attr_reader :param2, :param2
note that read and write ability has to be granted separately. However it turns out that all this can be shortened still further with attr_accessor :parm1, :param2
With methods you can use the private, protected and public keywords as a prefix (if absent, assumed public). Curiously the constructor is private where as in java it’s public
When a Rubist say class scoped variables they are talking about what you and me call static variables. Static variables are accessed with a @@ prefix. To learn more about variables and how Ruby pays homage to perl. visit: http://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Variables_and_Constants
Also available are static methods
These poor souls are only allowed to access class scoped things. The method call looks like as Myclass.static_baby
Modules and require
Worshippers of many ‘object oriented languages’ argue that multiple inheritance is evil, all the while twisting themselves into awkward shapes to overcome the lack of multiple inheritance. In Ruby, Modules is the workaround of lack of multiple inheritance. Modules can be ‘include’d in a class
And lastly all this is tied together with good old require which is like require_once in PHP and allows you to scatter your code through several files.
Oh did I tell you that if statements need to have a ‘then’
Ruby has a ternary operator
You can append an if conditional to the end of a statement exactly like you do in perl. This is called a statement modifier. Rubists say perl is impossible to read, I wonder why.
puts “i am fat” if weight > 10
you can append an if conditional to a begin end block but why anyone would want to do such a thing isn’t properly explained.
The while and the until conditionals can also be appended to the end of a statement, it’s called the loop modifier construct. By placing the while or until to the end of a begin/end block the do/while behaviour can be observed. In other words you can create a loop which is executed at least once.
Ruby sure has switch/case badly mixed up but then so does SQL. In Ruby case is used instead of switch, when instead of case and else instead of default, which is exactly the way it’s done in stored procedures. Also possible is the ‘target less’ mode that you use on ordinary SQL statements. That is the ‘case constant’ changes to just plain old ‘case’ and ‘when’ changes to ‘when condition’, ‘when condition2’ and so on. The advantage of the second form of course is that you are not just testing for equality which is the limitation in languages like PHP.
The break keyword in C like Switch case is not needed because one does not fall through a when. That’s a good thing because fall through in C switch case wasn’t a very hot idea in the first place.
Just because break is not needed with switch case doesn’t mean it’s absent. It exists! and is intended to be used to break out of a loop. The continue of C is replaced by next. A nicety is that an if conditional can be appended to a break (since it’s just another statement) then it’s known as a statment modifier
The for loop in ruby isn’t the for loop in C (isn’t that becoming a recurring theme?) it’s the for loop in python (not that I remember it too well) but it does taste a bit like foreach in PHP. It’s also like a substitute for ruby each (see above)
Ruby replaces try and catch with rescue, that certainly makes life a lot easier. Just add rescue nameOfException => e after your code. The => e is optional. Use it if you don’t want access to an instance of the exception to play with. Here is an example from the Ruby programming guide.
opFile = File.open(opName, "w") begin # Exceptions raised by this code will # be caught by the following rescue clause while data = socket.read(512) opFile.write(data) end rescue SystemCallError $stderr.print "IO failed: " + $! opFile.close File.delete(opName) raise end
You can use else to deal with situations where exceptions doesn’t occur. The documentation doesn’t say whether trying to cause confusion was a secondary objective or not. You can cause more trouble for yourself by using the ‘retry’ keyword. As the name suggests, it retries to execute the code block that produced the exception.
The finally keyword of Java is replaced by ensure and throw by raise. Like the other conditionals we have seen, rescue can also be used as a statement modifier
To ensure that people familiar with other programming languages have a hard time of it, and to make sure that Ruby code is spagetti code, they have added catch and throw but the meaning is very different from the keyword pair in other languagese. In ruby there are used to make ‘goto’ or spagetti
It’s past 1:30 in the morning and time to catch a few winks. There is still some time left before the 24 hours are used up.