Class Models for Lua

# Event Publisher

## `loop.object.Publisher`

Class of objects that delegate all method executions to a group of subscriber objects. Such objects behave like instances of Wrapper but delegate method invocations to a group of objects instead of a single one. This class is useful to implement event notification mechanisms or to let event notifications destined for a single object to be captured by many.

Like in the Wrapper class, only one single special method is used to spread the call event for all delegated methods of all publishers without creating temporary closures or any other kind of structure. However, this mechanisms only work for method calls done with the `:` operator. Again, similar to the Wrapper, the `self` parameter is properly replaced by the destiny object in every method call. The publisher object can also be invoked as a function or can receive key-value mappings (i.e `newindex` event). In such cases the same event is perfomed over the delegated objects. Such objects are stored in the publisher object with any valid table key.

## Behavior

### Meta-Fields

`__index`
  Setup the special delegation method in order to delegate the execution of the method indexed to all objects stored in the publisher.
`__newindex`
  Delegates any key-value mapping performed on the publisher to the objects stored in the publisher.
`__call`
  Delegates calls performed on the publisher to the objects stored in the publisher.

## Remarks

- Use function `rawset` to store objects in the publisher otherwise the `newindex` event will be propagated to the deletaged objects.
- Only one single Lua function is used to perform the delegation of all methods indexed in every `Publisher` instance. Therefore all indexed methods of the `Publisher` instance itself are the same function no matter if they are have different names.
- The `:` operator guarantees that the method index and execution is an atomic operation thus it is guaranteed that the setup performed by meta-method `__index` on the delegation function is preserved until the delegation method execution. If the method index and execution are not performed atomically the results are unpredictable because the delegation function settings may change by another method invocation.
- If you register an object in the publisher with a string key then you won't be able to invoke methods with that name.

## Examples

### File handler that outputs to two different files.

    local Publisher = require "loop.object.Publisher"

    file = Publisher{
    	io.stderr,
    	assert(io.open("errors.log", "w")),
    }

    file:write("This text is being written ")
    file:write("into two files simultaneously.")

    file:close() -- 'io.stderr' is now closed.

Copyright (C) 2004-2008 Tecgraf, PUC-Rio

This project is currently being maintained by Tecgraf at PUC-Rio.