Weird, weirder, ruby blocks in defined methods
module ActiveRecord class Base # Adds the uri getter an setter to the current # class def self.has_uri_field(uri_type) # Initializer takes the uri field define_method("initialize") do |uri| super(nil) # <--- NOTE THIS! write_attribute(:uri, uri.to_s) end ...
Later on, I use this to create a new ActiveRecord class with
class SourceRecord < ActiveRecord::Base has_uri_field MyUriClass
In the new class, the “initialize” method is dynamically overwritten with the method from the first code snippet. And now for the weirdness: I got to a point where I called
SourceRecord.new("uristring")
and the new initializer gets executed. In turn, it calls super, the ActiveRecord::Base initializer. Which, in turn, contains the following pice of code:
result = yield self if block_given?
The thing is that block_given? returns true and calls the Rails::Initializer.run block from environment.rb, passing an ActiveRecord as the config. Of course it fails miserably.
I have no idea where this block comes from. Inside the dynamically defined method it’s not existent (methods created with define_method don’t take blocks in 1.8). The stack trace is inconclusive. Of course the debugger fails to go there. At the moment I can work around with
super(nil) { nil }
which passes a useless block (which seems to work right), but the mystery remains.