« PostgreSQL Addendum | Main | One Language to Rule them All »

Rubyisms

Most rubyisms are convention based, meaning that they are not strictly enforced by the language/interpreter. Hear is my cheat sheet to help orient those new to ruby with some of these conventions without having to dig through the documentation.

Variables & Class Naming Conventions

  • Local Variables, Methods, and Parameters - always start with a lower case character or an underscore
  • Globals - prefixed with a $
  • Instance Variables - prefixed with a @
  • Class Variables - prefixed with a @@. These type of variables imply that there is only a single instance for the entire class. This does not however, imply public visibility.
  • Class Methods - prefix with class name class.method

Access Control

  • public - no access control; the default visibility applied. The only exception is the initialized method which is always private.
  • protected - limited visibility to an instance of the class and subclasses.
  • private - cannot be called with an explicit receiver. Visible only within the class.

Iterators

Code blocks can be dynamically associated with method invocations. The can be used to implement call backs, pass around chunks of code, and to implement iterators.

Code blocks are delimited by {} or the following key words :

do
   ...
   ...
end

The block is invoked in the receiver with a call to yield.

A callblock has the following form :

{|parameter1, .... parametern| argument1, .... argumentn}

The parameters are the values that will be used by the arguments.

Quirks

  • gets stores the input into a global variable $_
  • $_ is the default input for most cases.
  • don't create your own Observer class .... fucks things up.

Troubleshooting

  • Attribute setter not being called. Within an object, Ruby will parse setter= as an assignment to a local variable, not as a method call. Use self.setter= to indicate the method call.
  • A parse error at the last line of the source often indicates a missing end keyword.
  • Make sure that the type of the object you are using is what you think it is. If in doubt, use Object#type to check the type of an object.
  • Make sure that your methods start with a lowercase letter and that classes and constants start with an uppercase letter.
  • If you happen to forget a ``,'' in an argument list---especially to print---you can produce some very odd error messages.
  • Block parameters are actually local variables. If an existing local of the same name exists when the block executes, that variable will be modified by the call to the block. This may or may not be a good thing.
  • Watch out for precedence, especially when using {} instead of do/end.
  • Make sure that the open parenthesis of a method's parameter list butts up against the end of the method name with no intervening spaces.
  • Output written to a terminal may be buffered. This means that you may not see a message you write immediately. In addition, if you write messages to both $stdout and $stderr, the output may not appear in the order you were expecting. Always use nonbuffered I/O (set sync=true) for debug messages.
  • If numbers don't come out right, perhaps they're strings. Text read from a file will be a String, and will not be automatically converted to a number by Ruby. A call to to_i will work wonders. A common mistake Perl programmers make is:

    while gets
      num1, num2 = split /,/
      # ...
    end
    
  • Unintended aliasing---if you are using an object as the key of a hash, make sure it doesn't change its hash value (or arrange to call Hash#rehash if it does).
  • Use trace_var to watch when a variable changes value.
  • Use the debugger.
  • Use Object#freeze. If you suspect that some unknown portion of code is setting a variable to a bogus value, try freezing the variable. The culprit will then be caught during the attempt to modify the variable.

Performance

These idioms will help close the distance in performance between native code versus interpreted code generated by ruby:
  • Create locals outside of code blocks to prevent reinstantiation of iterator variables.
  • Use the included profiler. This feature can be invoked by either including the -r profile argument to the interpreter or adding the require 'profile' directive to your code.
Got your own Rubyisms? Just add them below.

TrackBack

TrackBack URL for this entry:
http://www.z1r0.com/mt/mt-tb.cgi/60

Post a comment

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)

About

This page contains a single entry from the blog posted on November 20, 2008 6:02 PM.

Many more can be found on the main index page or by looking through the archives.

Colophon

Creative Commons License
This weblog is licensed under a Creative Commons License.