On Tue, Sep 19, 2006 at 06:56:24AM +0900, Christian Neukirchen wrote: > Devin Mullins <twifkak / comcast.net> writes: > > Also, once you find an incompatibility, you can write code that works > > in both versions. Simple example from Rails: > > unless defined? instance_exec # 1.9 > > def instance_exec(*arguments, &block) > > block.bind(self)[*arguments] > > end > > end > > (Runtime #ifdef, if you will.) So you shouldn't need to maintain > > multiple versions of the code. > > OT: I must be dumb, but if it was that easy, why did Mauricio > Fernandez need almost a page of code to produce a good instance_exec? For the sake of future googlers... Getting a more or less working implementation is easy, but things become harder if you try to make it: * thread-safe * work with immediate objects * work with frozen objects * bounded-space (i.e. not leak memory on each call) ... [And anticipating such corner cases is even harder :)] As said elsewhere in this thread, Rails' version relies on Proc#bind, defined as class Proc #:nodoc: def bind(object) block, time = self, Time.now (class << object; self end).class_eval do method_name = "__bind_#{time.to_i}_#{time.usec}" define_method(method_name, &block) method = instance_method(method_name) remove_method(method_name) method end.bind(object) end end This implementation * is not strictly thread-safe (in practice, it will be, since I doubt Ruby will switch contexts in under 1us on any machine) * doesn't work with immediate (Fixnums, etc.) nor frozen objects * leaks memory [1] (around 70 bytes per #instance_exec call) I've analyzed several #instance_exec implementations [2] and written a thread-safe, bounded-space one that works with frozen and immediate objects [3]. 1. http://eigenclass.org/hiki.rb?ruby+symbols+memleak 2. http://eigenclass.org/hiki.rb?instance_exec 3. http://eigenclass.org/hiki.rb?bounded+space+instance_exec -- Mauricio Fernandez - http://eigenclass.org - singular Ruby