weissjeffm / multimethods

Multimethods for Python, inspired by Clojure
Other
16 stars 3 forks source link

Defining multiple methods seems to be broken in 0.3.0 #3

Closed jsofra closed 10 years ago

jsofra commented 10 years ago

Defining multiple methods seems to be broken for me in 0.3.0 using Python 2.7.

The defining of a method seems to wipe out the 'method' attribute of the MultiMethod object.

The following interaction shows the problem:

| >>> from multimethods import MultiMethod, Default | >>> def dispatch_combine(x, y): | ... return (type(x), type(y)) | ... | >>> combine = MultiMethod('combine', dispatch_combine) | >>> dir(combine) | ['call', 'class', 'delattr', 'dict', 'doc', 'format', 'getattribute', 'hash', 'init', 'module', 'name', 'new', 'reduce', 'reduce_ex', 'repr', 'setattr', 'sizeof', 'str', 'subclasshook', 'weakref', '_dominates', '_prefers', 'addmethod', 'dispatchfn', 'find_best_method', 'get_method', 'method', 'methods', 'prefer', 'preferences', 'removemethod'] | >>> @combine.method((int, int)) | ... def combine(x, y): | ... return x * y | ... | >>> dir(combine) | ['call', 'class', 'closure', 'code', 'defaults', 'delattr', 'dict', 'doc', 'format', 'get', 'getattribute', 'globals', 'hash', 'init', 'module', 'name', 'new', 'reduce', 'reduce_ex', 'repr', 'setattr', 'sizeof', 'str', 'subclasshook', 'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name'] | >>> @combine.method((str, str)) | ... def combine(x, y): | ... return x + '&' + y | ... | Traceback (most recent call last): | File "", line 1, in | AttributeError: 'function' object has no attribute 'method' | >>>

weissjeffm commented 10 years ago

Strange, the unit tests add more than one method, so there must be more to it than that. I'll run your exact scenario shortly.

weissjeffm commented 10 years ago

Ah I see the problem, you are clobbering the multimethod when you define a dispatch function with the same name.

Try it this way:

from multimethods import MultiMethod, Default
def dispatch_combine(x, y):
    return (type(x), type(y))
combine = MultiMethod('combine', dispatch_combine)

@combine.method((int, int))
def _combine_ints(x, y):
    return x * y

You can also add methods explicitly if you prefer to use lambdas, but I don't normally test this:

combine.addmethod(lambda x,y: x*y, (int, int))
jsofra commented 10 years ago

Thanks Jeff, I'll try that. By the way my example is directly from your README on github so if it does not work you might want to update the README page.

Cheers, James

On Wed, May 28, 2014 at 8:51 PM, Jeff Weiss notifications@github.comwrote:

Closed #3 https://github.com/weissjeffm/multimethods/issues/3.

— Reply to this email directly or view it on GitHubhttps://github.com/weissjeffm/multimethods/issues/3#event-125494979 .

weissjeffm commented 10 years ago

Ok, I'll update the docs and close this when complete. I'll also fix up calling addmethod directly (those arguments should be in the opposite order, and I don't have unit tests for that yet).

jsofra commented 10 years ago

Thanks again, just tried out your suggestion and that is working for me.

On Wed, May 28, 2014 at 9:28 PM, Jeff Weiss notifications@github.comwrote:

Ok, I'll update the docs and close this when complete. I'll also fix up calling addmethod directly (those arguments should be in the opposite order, and I don't have unit tests for that yet).

— Reply to this email directly or view it on GitHubhttps://github.com/weissjeffm/multimethods/issues/3#issuecomment-44394612 .

weissjeffm commented 10 years ago

Great. The original version of this lib, you could name the dispatch functions the same, but I ended up changing that to get some other desired behavior and didn't notice the docs needed updating.

weissjeffm commented 10 years ago

Fixed in 56a01b7aec

Note just pushed 0.4.0 which fixes bad method names: addmethod(f, dv) -> add_method(dv, f) removemethod(dv) -> remove_method(dv)

I hadn't documented these methods in the readme so I figured it's not too late to change those.

jsofra commented 10 years ago

Hi all,

My gmail account was compromised this morning. I believe I have secured the account again.

Sorry for the SPAM, if you received an email for this account in the last couple of hours it would probably be prudent to delete it and not follow any of the links.

Cheers, James Sofra