当前位置:  开发笔记 > 后端 > 正文

Ruby中.NET事件的等价物是什么?

如何解决《Ruby中.NET事件的等价物是什么?》经验,为你挑选了2个好方法。

问题很简单.对象需要通知观察者可能感兴趣的一些事件.

当我坐下来验证我现在在Ruby中编写的设计只是为了验证它.我发现自己难以理解如何实现对象事件.在.Net中,这将是一个单行程.. .Net也可以执行处理程序方法签名验证等.例如

// Object with events
public delegate void HandlerSignature(int a);
public event HandlerSignature MyEvent;
public event HandlerSignature AnotherCriticalEvent;

// Client
MyObject.MyEvent += new HandlerSignature(MyHandlerMethod); // MyHandlerMethod has same signature as delegate

是否有一个EventDispatcher模块或者我缺少的东西,我可以绑定到Ruby类?希望得到一个符合Ruby最少惊喜原则的答案. 事件将是事件的名称加上在事件发生时需要调用的[observer,methodName]对象的队列.



1> janm..:

首先,在Ruby中没有方法签名.最接近的是检查函数的arity.鸭子打字需要不同的思考(略).

可观察到的模块是一个开始,但如果你有一个要求,有从单一类中的多个事件,它可能是不够的.

这是一个快速草图.它支持方法和块.根据需要进行修改以适应您的代码,线程方法等.例如,您可以使用method_missing在方法名称中包含事件名称,而不是将其作为参数.

class EventBase
    def initialize
        @listeners = Hash.new
    end

    def listen_event(name, *func, &p)
        if p
            (@listeners[name] ||= Array.new) << p
        else
            (@listeners[name] ||= Array.new) << func[0]
        end
    end

    def ignore_event(name, func)
        return if !@listeners.has_key?(name)
        @listeners[name].delete_if { |o| o == func }
    end

    def trigger_event(name, *args)
        return if !@listeners.has_key?(name)
        @listeners[name].each { |f| f.call(*args) }
    end
end


class MyClass < EventBase
    def raise_event1(*args)
        trigger_event(:event1, *args)
    end

    def raise_event2(*args)
        trigger_event(:event2, *args)
    end
end

class TestListener
    def initialize(source)
        source.listen_event(:event1, method(:event1_arrival))
        source.listen_event(:event2) do |*a|
            puts "event 2 arrival, args #{a}"
        end
    end

    def event1_arrival(*a)
        puts "Event 1 arrived, args #{a}"
    end
end

s = MyClass.new
l = TestListener.new(s)

s.raise_event1("here is event 1")
s.raise_event2("here is event 2")



2> 小智..:

为什么不写自己的事件类?就像是

class Event
  def initialize
    @handlers = Array.new
  end

  def fire
    @handlers.each do |v|
      v.call
    end
  end

  def << handler
    @handlers << handler
  end
end

e = Event.new

e << lambda { puts "hello" }
e << lambda { puts "test" }
e.fire

这只是一个最小的样本,但可以以任何方式扩展.在.Net中添加像sender和eventArgs这样的参数,或者你喜欢的任何东西;-)

推荐阅读
手机用户2402852307
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有