Ruby on Rails
I decided to finally learn Ruby on Rails.I am an old C and Perl programmer and have done a lot of Perl OO programming. I knew that Ruby was similar to Perl in some ways, so I figured learning it would not be too difficult. I also had some experience with administering Rails in a previous life and I was familiar enough with the framework.
Ruby being purely OO took a little getting used to, but it was not difficult to pick up the concepts. As usual the most daunting issue was learning all the method names and what they did in order to write decent and compact code. For the most part Ruby is similar enough to Perl in its general construction that the syntax was not too hard. I found it interesting that the statement syntax is generally pretty sparse. For example an if statement does not require block delimiters. It can be written as:
if <conditional>
....
.....
end
Also statements do not require a terminating ";" as they do in Perl and C if there is just one statement per line. This reminded me of some work I did on the Pascal compiler in the 70s which relaxed Pascal's syntax when a newline was encountered after a statement left off the terminating ";". In Pascal's case the ";" was a statement delimiter, but the idea was similar. The modifications were adopted by the CS Department at the University of Texas at Austin and it reduced the number of batch runs (this was in the days of card decks) required, since a common Pascal error was leaving off what seemed like redundant semicolons.
The same if statement in Perl requires parens around the conditional and a block. e.g.
if (conditional) {
....
....
}
This makes (at least this part) of the Perl parser somewhat simpler. Ruby appears to adopt a minimalist approach and leaves out the syntactic sugar which if you understand parsing technology is relatively easy to do.
The most interesting Ruby feature was the use of what I will call parameterized blocks. It is common in Ruby to have constructs like:
a.each { |element| puts element, "\n" }
This looks like a Java interator, but there is more to this than meets the eye at first glance. You can think of the block as an additional parameter passed to the each method. The block is in fact a closure. When the method is called, there is a statement in the method code called yield which is replaced with the code in the block. The arguments between the pipe symbols replaces the parameters defined in the yield statement.
This is equivalent to creating a closure and passing it as an argument to the method and then calling the closure with the arguments. In Perl the above would look something like:
#! /usr/bin/perl -w
package TIC::Array;
sub new {
my $proto = shift;
my $init = shift;my $class = ref($proto) || $proto;
my $self = $init;
bless $self, $class;
return $self
}sub each {
my $self = shift;
my $block = shift;for my $x (@$self) {
&$block($x);
}
}
1;my $a = TIC::Array->new([1,2,3,4,5,6]);
my $block = sub {
my $arg = shift;print $arg, "\n";
};
$a->each($block);
Obviously, the Perl approach is more primitive. But Perl OO programming tends to be closer to the ground than other OO languages.
Curiously, I am finding I am starting to not type the required semicolons when I write Perl, since I have gotten used to the Ruby syntax. I guess you really do learn programming language syntax in the spine.
- smoot's blog
- Login or register to post comments
