Apr 13, 2007 @ 09:17 am

When you are inside a class, you are not always forced to use the self receiver explicitly when calling a method residing in the same class (or higher in the hieararchy). However, there is a time when you HAVE to use self or else it just won’t do what you want : This time is when you call an attribute writer.

  1. class Test
  2.   def assign_fiesta=(value)
  3.     @assigned_value=value
  4.   end
  5.  
  6.   def not_an_assignment
  7.     @assigned_value
  8.   end
  9.  
  10.   def some_method()
  11.      not_an_assignment # <== self is implicit
  12.      assign_fiesta = "Hello!" # <== self is not implicit! assign_fiesta is a local variable
  13.      self.assign_fiesta = "Hello!" # <== Now we’re talking!
  14.   end
  15. end

Why is this so? Well, it makes some sense when you think about it. If your attribute writers (methods trailing with an = sign) would’nt require to be called with an explicit receiver, how could you tell ruby when you want to assign to a local variable instead of calling a method? Sure, ruby could check if the thing to the left corresponded to the name of a method in the current class and, based on the answer, call a method or assign to a local variable. But what if the method did not reside in the current class but in the parent class… or in the parent class of the parent class (and so on)? It would become a great source of confusion, don’t you think?

Say for example you had a method in your class that was setting the local variable color (color=”blue”). This method could work without any problem for months… until you decide to add a new attribute writer with the name color= in the parent class. From now on (that is, if ruby would be using some detection technique like the one mentionned earlier), your initial method would not deal with the local variable color anymore, it would call the color= method in the parent class! This could get really messy and error prone.

So, instead of trying to guess if the thing to the left is a method with a trailing = sign or a local variable, ruby assumes that it is always a local variable and that the whole expression is a standard assignment. That being said, you could use self only to call attribute writers and omit it for other methods… but personally I don’t like that kind of inconsistency.

I like to remind myself that a method never floats in the air and that it is always contained into an object. That’s why most of the time I prefer to specify the receiver before the name of a method… no wonder if I’m outside or inside the object.

Bookmark this post : These icons link to social bookmarking sites where readers can share and discover new web pages.
  • DZone
  • Reddit
  • del.icio.us
  • Digg
  • Furl
  • Technorati
  • StumbleUpon
Rate this post :
1 Star2 Stars3 Stars4 Stars5 Stars (1 votes, average: 5 out of 5)
Loading ... Loading ...
Posted under : In depth
4 Comments
MyAvatars 0.2

This is one of those simple things I didn’t know until I read Ruby for Rails. I highly recommend that book for illuminating numerous small details like this. Pickaxe is a great reference, but it glosses over a lot of those details in favor of a comprehensive picture of the language.

Another one of these little gotchas is that referencing a non-existent local variable or method raises an exception, whereas a non-existent instance variable returns nil.

Comment by : Gabe
— April 17, 2007 @ 2:52 pm

MyAvatars 0.2

[…] The answer lies in the fact that Ruby requires an explicit self reference when using attribute writers (aka, property setters) within the class itself. This feels clunky to me, but for your information, here’s a rationalisation of the explicit self requirement. […]

— July 28, 2007 @ 5:20 am

MyAvatars 0.2

[…] at least one case that requires self as an explicit reciever: when calling an attribute writer. Otherwise you’re just shadowing the attribute writer method locally. It’s not clear […]


MyAvatars 0.2

[…] @self.author_id=1@ as making a method call. Which makes perfect sense when you think about it see “Use self explicitly” for more details. (thanks to Craig Webster and Florian Gilcher, via Twitter for clearing this up […]





Leave a comment
Name (required)
Email (will not be publish) (required)
Website