Gozala/method — pull request #7 by Gozala (2013-03-11 16:21:57+00:00)
Title: Attempt to fix a dedup problem.

I think I may finally found fix or rather workaround for the npm dedup issue. Little overview of the issue:

## Issue

With npm it's super likely that you will end up with copies of the same library. If that library uses method based functions each copy will end with a different method and even though
library is the same functions won't be able to interact as desired. Here is an example illustrating the case:

```
example@0.0.0 /Users/gozala/Projects/example
├─┬ dom-reduce@1.0.0
│ └──┬─ reducible@1.0.5
│ └── method@1.0.2
└─┬ reducers@2.0.0
└─┬─ reducible@1.0.5
└── method@1.0.2
```

In that example app depends no `dom-reduce` that depends on `reducible` in order
to extend it, so that support for DOM event can be added. App also depends on
`reducers` that also depends on `redubicle` to implement high order APIs on top
of core ones provided by `reducible`.

The problem with a above picture is that `dom-reduce` will end up extending one
`redubile` while `reducers` will end up using a different copy that will have no
extensions. Things get even messier with more dependencies and different versions
of libraries.

What user expects is that extensions defined by `dom-reduce` will be available for
`reducers`.

## Solution

Main objective of method library is to allow loose coupling of components
such that extensions can be defined independently, from definitions. But
since npm makes identities unreliable and there are no intents to fix that
method library should workaround it by it's own. What we need is make
method names such that they will be linked to a module defining it.

From a user perspective method `reduce` defined by `reducbile/reduce.js`
is one they expect to get regardless of where that may be coming from.
There for the most reasonable solution would be to use
`reducible/reduce.js#reduce` as an identity of a method.

Luckily there is `module.parent.id` that is path to a module on the file system. From that we can extract module path like `reducbile/reduce.js` (Although I
wish `module.id` was that :) by subtracting path from last `node_modules` and
suffix that with method hint if provided or by generating random one to make
sure diff methods from same module won't collide.

## Outstanding issues

1. If package requiring method is "symlinked" it's `module.id` will be an
different from the installed one since linked won't find `node_modules`.
Probably this is not a big deal though likely if package `foo` is linked
it's likely because changes are being made to it, and there are no other
`foo` copies or they are linked as well.

Maybe we could even convince node to make `id` be actually
`package/path/to/module` and than this issue could be solved.

2. In `browserify@1.x` module is not even defined :( So this does not works
at all, but maybe we can fix that.