From: hemant Date: 2007-07-13T18:57:29+09:00 Subject: Re: Help with passing a callback method On 7/13/07, Micke Lax wrote: > Hi! > > I am trying to do the following. I can't get it to work, don't know if > it even is possible but it would be nice. If it is not possible to do it > the way I try here is there any other good approach? > > My reason to use a callback is to keep the code size down and avoid > duplicate code. in one case I would use create_xml_str and in the other > case create_h_str > > I have cut out a lot of code to keep the size down, tell me if you need > to see more. > > > ###-------------------------------------------------------------------- > ### header_data.rb > ###-------------------------------------------------------------------- > class Header_Data > def create_xml_str > # returns a xml-formated string > end > > def create_h_str > # returns a h-formated string > end > > end > > > ###-------------------------------------------------------------------- > ### header_data_array.rb > ###-------------------------------------------------------------------- > /.../ > class Header_Data_Array > > def interpret_layout(t, callback) > result = String.new > case > when (t.match(/empty/)) > result = "\n\n" > > when (t.match(/^\d{1,4}/)) > a = @data_array[t.to_i] > # here a tries to call the callback (crash...) > a.callback.call() > > when (t.match(/[A-Z]*/)) > result = create_subtitle_str(t) > > end > return result > end > > > > def create_file(file_name, layout) > # get the callback and pass it in the method call > function = Header_Data.new.method(:create_xml_string) > layout = layout.map{|l| interpret_layout(l, function)} > > end > /.../ Hey Mike, I think what you are trying to do is quite possible, I often use a callback class implementation like this: class Callback def initialize &block return unless block @callback ||= [] @callback << block end def callback &block @callback ||= [] @callback << block end def trigger *args while cb = @callback.shift cb.call(*args) end end end now from wherever you are calling method interpret_layout, before calling interpret_layout you can create an instance of Callback class and pass it to method interpret_layout. Something like this: callback = Callback.new { #soemthing that you need to do } interpret_layout(t,callback) now in method interpret_layout you can do this: callback.trigger some_arg and the block that you attached while creating the callback would be triggered.