How to implement a “callback” in Ruby?

后端 未结 7 1351
臣服心动
臣服心动 2020-12-12 10:00

I\'m not sure of the best idiom for C style call-backs in Ruby - or if there is something even better ( and less like C ). In C, I\'d do something like:

voi         


        
7条回答
  •  眼角桃花
    2020-12-12 10:35

    So, this may be very "un-ruby", and I am not a "professional" Ruby developer, so if you guys are going to smack be, be gentle please :)

    Ruby has a built-int module called Observer. I have not found it easy to use, but to be fair I did not give it much of a chance. In my projects I have resorted to creating my own EventHandler type (yes, I use C# a lot). Here is the basic structure:

    class EventHandler
    
      def initialize
        @client_map = {}
      end
    
      def add_listener(id, func)
        (@client_map[id.hash] ||= []) << func
      end
    
      def remove_listener(id)
        return @client_map.delete(id.hash)
      end
    
      def alert_listeners(*args)
        @client_map.each_value { |v| v.each { |func| func.call(*args) } }
      end
    
    end
    

    So, to use this I expose it as a readonly member of a class:

    class Foo
    
      attr_reader :some_value_changed
    
      def initialize
        @some_value_changed = EventHandler.new
      end
    
    end
    

    Clients of the "Foo" class can subscribe to an event like this:

    foo.some_value_changed.add_listener(self, lambda { some_func })
    

    I am sure this is not idiomatic Ruby and I am just shoehorning my C# experience into a new language, but it has worked for me.

提交回复
热议问题