Help with passing a callback method

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
/.../

--
Posted via http://www.ruby-forum.com/.

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.

I'd rather here where you want to put the callback and what it is
supposed to do.

The generic answer would be: use a block as callback. You can even
store it somewhere or pass it on:

def foo(&b)
  puts "calling"
  b.call
end

def bar(&x)
  puts "delegating"
  foo(&x)
end

bar do
  puts "block"
end

###--------------------------------------------------------------------
### 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
/.../

Kind regards

robert

···

2007/7/13, Micke Lax <mickelax@yahoo.se>:

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.

···

On 7/13/07, Micke Lax <mickelax@yahoo.se> 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
/.../

> 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.

I'd rather here where you want to put the callback and what it is
supposed to do.

The generic answer would be: use a block as callback. You can even
store it somewhere or pass it on:

def foo(&b)
  puts "calling"
  b.call
end

def bar(&x)
  puts "delegating"
  foo(&x)
end

bar do
  puts "block"
end

Damn you Robert. :slight_smile:

···

On 7/13/07, Robert Klemme <shortcutter@googlemail.com> wrote:

2007/7/13, Micke Lax <mickelax@yahoo.se>:

> ###--------------------------------------------------------------------
> ### 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
> /.../

Kind regards

robert

--
gnufied
-----------
There was only one Road; that it was like a great river: its springs
were at every doorstep, and every path was its tributary.
http://people.inxsasia.com/hemant

Thanks for the quick replies guys!

I'll try it out now and let you know how it went

-- Micke

···

--
Posted via http://www.ruby-forum.com/.