Category: ruby

Difference between do-end and {} blocks

Posted by on February 7, 2010

There is a important difference between the two block syntaxes in Ruby: Their precedence.
Consider following code:

def method1(*args)
  puts "method1 got a block" if block_given?
end
 
def method2(*args)
  puts "method2 got a block" if block_given?
end
 
method1 method2 do
end
 
method1 method2 {
}

You would expect both method calls to produce the same result, wouldn’t you?
Output:

method1 got a block
method2 got a block

Obviously the do-end block is passed to the first method in the expression while the {} block is passed to the method called directly before it.
Another example shows that the assignment does not count as a method call here:

#[...]
class Foo
  def bar=(o)
    puts "Foo#bar= got a block" if block_given?
  end
end
foo = Foo.new
 
foo.bar = method1 method2 do
end 
#method1 got a block
 
foo.bar = method1 method2 {
} 
#method2 got a block

Sequel single table inheritance

Posted by on October 20, 2009

Sequel’s STI is not so well documented as ActiveRecord’s is. Because it cost me about 20 minutes to find out about it’s syntax, I post a little example.

class A < Sequel::Model
  plugin :single_table_inheritance, :object_type
end
 
class B < A
end

The second argument is the name of the column to be used to store the class name in DB. Don’t use ‘type’ here, it collides with Ruby’s Object#type.
This works with version 3.5.0 and should work with any version >= 2.12.0.

Monkeybars – Little bug

Posted by on September 10, 2009

For a little side project I am currently evaluating different ways of GUI programming using Ruby. Monkeybars is one of the most interesting candidates. There is a really good article about it, if you want to learn more.
Version 1.0.4 has a little, but annoying bug: If you generate a new application skeleton it won’t compile/run:

manifest.rb:32:in `require': no such file to load -- monkeybars (LoadError)
	from manifest.rb:32
	from manifest.rb:21:in `require'
	from main.rb:21

To fix it, you got to change line 21 of manifest.rb:

add_to_classpath '../lib/java/monkeybars-1.0.2.jar'
#to
add_to_classpath '../lib/java/monkeybars-1.0.4.jar'

Multi-line comments in ruby

Posted by on April 7, 2009

I keep forgetting how to do them, so I post myself a little reminder here.

Just put

=begin
...
=end

around the stuff to be commented out. There must not be whitespaces before these keywords.

Optimistic Locking for Datamapper

Posted by on October 1, 2008

Update(2009-3-3): dm-optlock now on github

Update(2009-1-10): New version

I should be learning for my test on next tuesday, but coding helps keeping me in a good mood.
Here is a little gem I will need in a future project for which I’ve choosen merb + datamapper. Datamapper doesn’t support any row level locking.
My code checks if the record you want to save was changed since you loaded it. If it was changed it raises an exception (DataMapper::StaleObjectError). It works quite like ActiveRecord’s optimistic locking.
You need to define this column in your model you want to be locked:

property :lock_version, Integer, :default => 0

Anywhere in your code where you update your objects you should be prepared to handle the exception:

begin
  if @obj.update_attributes({:dummy => 123})
    #successful
  else
    #validation errors?
  end
rescue DataMapper::StaleObjectError
  #tell the user that he was too slow
  #or even better: show him the conflicts and let him merge the changes
end

The gem can be downloaded here:
dm-optlock-0.1.0.gem
Please let me know what you think of it. I’ll try and put it on RubyForge, too.

(00:27) Little update:
I added a ’set_locking_column’ method.
dm-optlock-0.1.2.gem

Update:
dm-optlock is on Rubyforge.
Now you can get it like this:

gem install dm-optlock