Ruby's Operator Precedence: More subtle than you might think

Posted by flori Wed, 08 Aug 2007 10:25:00 GMT

I just read Rick DeNatale's article about Ruby's Operator Precedence, in which he mentioned, that Ruby's and and or operators have a weaker precedence than && and || (and also weaker than =). This is similar to Perl's and and or operators, and the reason why I use the following rules of thumb for the use of the different operators in both languages:

  1. Use && and || for expressions (especially more complex ones) like a = a && b || c.
  2. Use and and or instead of if enabled then do_it end or do_it if enabled as in enabled and do_it.
  3. Or use and and or for very simple expressions as in if a and b then ... end.

Rule 3 exists only, because I think it is slightly more readable to use and or or than && and ||. This advantage goes pretty much away if you have to start using parentheses to render more complex expressions unambiguous. It could as well be dropped.

But in Ruby other than in Perl there is another reason for rule 3:

Ruby's and and or operators have the SAME precedence!

Yeah, you read this right: So, for example, true || true && false # => true, but true or true and false # => false.

This is a rather surprising (as in unfortunate) peculiarity of Ruby, and I do not think, that it is a good idea. I guess most people are unaware of this issue, and their code does only work by accident - until it stops doing so for unknown reasons. Matz' rationalisation of this behaviour (somewhere on ruby-talk) was "'and' and 'or' don't have different precedence in English either." It didn't convince me then and doesn't convince me now: We don't program in English, because it is too unprecise. Why burden Ruby with the same problem as well?

Tags ,  | no comments

Tail of emerge.log

Posted by flori Mon, 03 Apr 2006 12:53:00 GMT

I tailed my /var/log/emerge.log on one of my gentoo systems, and saw that they give the time in unixtime stamps (= seconds since the epoch). This is a bit difficult to interpret, so I came up with this short oneliner in Ruby, which converts the timestamp into ISO format (my fav!):

ruby -pe 'sub /\d+/, Time.at($&.to_i).strftime("%F %T")'

This is quite short, and it's usually difficult to do such small tasks in Ruby shorter than in Perl. This is my version of this oneliner in Perl:

perl -MPOSIX -pe 's/\d+/strftime("%F %T", localtime($&))/e'

It's a few characters longer, but not much. It's easy to see from this example, that Ruby and Perl are very similar, especially regarding command line options and special $-variables. Well, I guess Ruby was a bit "inspired" by Perl. But somehow I like the Ruby oneliner better and it seems clearer to me (and it doesn't require loading a special module). To use Perl's black magic /e modifier, always seemed to be a bit dirty to me as well.

Disclaimer: I might be quite biased, I guess. ;)

Tags , , ,  | no comments