From: Trans Date: 2006-11-13T03:15:05+09:00 Subject: Re: redefining a method using Module#include me@mikehogan.net wrote: > Hi, > > How can I redefine Array#[] using an included Module? Here is my > attempt: > > module AbsenceHandling > def if_absent_call(p) > @if_absent = p > self > end > > def [](index) > result = old_accessor(index) > if(result.nil? && !@if_absent.nil?) > result = @if_absent.call(index) > self[index]=result > end > result > end > end > > class Array > alias :old_accessor :[] > include AbsenceHandling > end > > > x = [1,2,3].if_absent_call(proc{|index| > "#{index}" > }) > puts x[5] There are a number of ways. To be clear you are asking for code inject rather then inheritance. traditionally subclasses are used add functionality, But with Ruby we have the power to directly effect core classes. In doing so first ask yourself if you really need a module. If not the simple do: class Array def if_absent_call(p) ... alias :old_accessor :[] def [](index) ... The next levelup gets more complicated one way is to use the #included callback to inject the code directly, but this is a misrepresentation of what include should do (i.e. inheritance) and I strong discourage it. Another related approach is alias_method_chain supported by both ActiveSupport and Facets. Here is an example: module X def self.included(base) base.module_eval { alias_method_chain :foo, :feature } end def foo_with_feature foo_without_feature + '!' end end class Y def foo ; "FOO" ; end include X end y = Y.new assert_equal( "FOO!", y.foo ) But this would be a little tricker with an operator and it also has it's own downsides. Other solution you can look into are Facets' Module#prepend and Facets' Cut implementation. Having said all that, you know what you are attempting to do is dangerous stuff. Muckng with Array#[] may have sever side effects. In this case, I highly recommend using singleton instead: a = [] a.extend AbsenceHandling Just replace #old_accessor with #super. It's a case be case basis, but it's much safer and hek, it's easy :-) T.