On Thursday, September 19, 2002, at 06:05 PM, Ryan Davis wrote:

> I'm reasonably sure that it's not RubyInline that is causing this 
> problem. I'm still not sure what is, but it seems to be centered 
> around the following line:
> 	    Array.send(:alias_method, :thesum, meth.intern)

OK... I have a fix on the problem, but not a fix FOR the problem... It 
is definately caused by the above alias_method. Essentially, he aliases 
BEFORE the inline method is called, see below:

>> methods.each do |meth|
>>     Array.send(:alias_method, :thesum, meth.intern)
>>
>>     ...
>>       [0,1,2,3,4,5,6,7,8,9,10].thesum
>>     ...

so, :thesum winds up pointing to the original method :sum. But :sum is 
the method that calls inline, and inline runs the following:

     myclass.class_eval("include #{mod_name}")
     myclass.class_eval("alias_method :old_#{mymethod}, :#{mymethod}")
     myclass.class_eval("alias_method :#{mymethod}, :_#{mymethod}")

which move :sum to :old_sum, and :_sum (the extern version) to :sum.

His code then calls :thesum, which is a direct alias (ie reference) to 
(now) :old_sum which will call the dynamic loader over and over. In 
other words, he always runs the slowest possible version.

The first answer is "don't alias a method that calls inline", but is 
that reasonable? This would be where smalltalk's #becomes: method would 
really shine. All references to the old method would end up pointing to 
the new method... but #becomes: is hard to implement and dangerous 
(must shut down GC, manually walk object graph, etc). I'd rather ruby 
keep compiling and linking in 3 minutes on my system rather than be 
able to handle everything...

Is there a better way for me to handle this? Can I at all? Maybe some 
object_space madness? I don't think this is possible because I'd need 
access to, and the ability to change, every reference, not every object.