You Can't Judge a Book... Some Mental Traps in Learning Ruby

Posted by Rick DeNatale Wed, 17 Oct 2007 17:01:00 GMT

Quick, in the Ruby expression:
a[10]

What's the class of a?

Many beginning, and intermediate, rubyists whould instinctively say Array! The real answer is that given just this code, you don't know.

Recently, on the rails-talk mailing list there was a discussion of this idea from Jamis Buck. Jamis uses alias_method in ActiveRecord::Base so that he can use shortcuts like:

Person[1]

as a shortcut for:

Person.find(1)

This is particularly nice when playing with ActiveRecord in the rails console, but many seem to think that this should be made part of Rails core, and I don't see a real objection.

Now one objection raised by the folks who answer Array to the opening question is that, since ActiveRecord rows can be deleted, Person[2] might fail even though Person[1], and Person[3] work. The reasoning is that the [] makes it "look like an array" and arrays don't act like that.

To me this is a case of judging a book by looking at it's cover. Something which I strongly suggest needs to be resisted in order to achieve ruby mastery.

Let's have a look at a couple of "can't see past the cover" traps in Ruby.

Read more...

Posted in , ,  | 7 comments | no trackbacks

Ahh, the Subtleties of Ruby's Operator Precedence

Posted by Rick DeNatale Tue, 07 Aug 2007 19:24:00 GMT

Not long ago while working on an existing Rails application, (i.e. code I hadn’t written). I was mystified when a logical expression seemed to be returning an odd result. The expression had been written with not, and, and or, and was the right hand side of an assignment statement. ventually I changed to using !, &&, and || which fixed the problem. I never completely understood what was going on, until I encountered this blog entry by Jay Fields.

One of the big differences between Ruby and Smalltalk is the use of operator precedence. In Smalltalk, the grammar is very simple, unary message selectors bind tighter than binary selectors, which bind tighter than keyword selectors. The assignment operator binds more loosely than any of these. This is often a stumbling block for newcomers to Smalltalk when they find that in Smalltalk 3 + 5 * 2 evaluates to 16.

Ruby in comparison has quite a rich and flexible syntax. Usually, it’s quite intutitive, but, depending on where you come from there can be some surprises.

I understood the relative precendences of, say && vs. and in Ruby, but the fact that and had weaker precedence than = escaped me, until Jay’s article turned the light on for me.

As they say, you learn something new everyday, or at least you hope you do. I don’t expect that I’ll forget this little corner of Ruby in future

Posted in , ,  | Tags ,  | 1 comment | 1 trackback

Polishing That Chain

Posted by Rick DeNatale Tue, 12 Jun 2007 21:22:00 GMT

A few days back I wrote this:
The metaclass’ superclass is set to the metaclass of the classes superclass.

Since I first wrote it I’ve gotten some feedback that the last sentence is a little hard to digest, so I’ve added an example.

Let’s say we create a class MyNiftyClass as a subclass of Object. The singleton class of the class object referenced by the MyNiftyClass global gets created at the same time as class object, no waiting for one of the things which trigger the creation of a singleton class for a non-class object. Thesuperclass of the MyNiftyClass is set to object, and the superclass of MyNiftyClass’ metaclass is set to Object’s metaclass.

Besides the fact that their creation occurs immediately, there is one other difference between singleton classes of objects and singleton classes used as metaclasses. The later can have subclasses, while the former cannot.

I’ve gone back and editted the original post, but I’ve summarized it here in case anyone else has actually already read it.

Posted in ,  | 1 comment

Update on Continuations

Posted by Rick DeNatale Wed, 06 Jun 2007 21:00:00 GMT

Robert Dober discovered that the continuation example which I gave in last night’s article behaves badly if you run it with ruby rather than irb.

I’ve made note of this in the original article, and I’ve added a simpler example which does work under ruby. I’ll try to come back with a new article which shows an example of how continuations are normally used.

Posted in ,  | Tags ,  | no comments

Closing in on Closures and Jumping into Continuations

Posted by Rick DeNatale Wed, 06 Jun 2007 01:41:00 GMT

Recently on ruby-talk someone asked if continuations and closures were the same thing.

They are related in that they both are tied to a particular point in time in the execution of a program. The difference is that closures are like a souvenir of a trip, while continuations are like a kind of time-machine. Read more...

Posted in ,  | Tags ,  | no comments

Chain, Chain, Chain

Posted by Rick DeNatale Sat, 02 Jun 2007 22:28:00 GMT

I’ve noticed some confusion lately on the part of some newcomers to Ruby about how methods are found at runtime, and in particular, the relationship between instance and class methods.

A week or so ago, someone posted some questions on ruby-talk about this issue, and then today I ran across this blog review of David Black’s “Ruby for Rails” which contained this:

On every method call, Ruby will search its object space in the following order:
  1. Current instance, followed by class methods
  2. Mixed in methods
  3. Superclass instance (repeat 1)
  4. Object methods, followed by Kernel mixin

I often get confused with mixin, class, and instance method precedence, so this is a useful model to revisit and keep in mind.

I don’t know where that reference to class methods in item 1 came from. I don’t think David said that in his book.

Here’s how it really works

Here in the form of answers to the questions posed on ruby-talk last week is my explanation of how Ruby finds methods when a message is sent to an object

Read more...

Posted in ,  | Tags , ,  | 1 comment