None. Even with Java's typesystem you can know whether the thing or things you have in your hand implements some interface or not ("callable" in this case) at compile time. You can't ask this question because you can't not already know the answer.
I'm not speaking to whether dynamic/duck typing is good or bad here, just pointing out that the question is flawed.
I believe the question is asking 'if you have an object of unknown type, how do you introspect it to find out if it supports a method with name meth_name'. the test for callability is to determine of the objects member is callable, not if the object itself is callable.
Java's reflection system exists to answer this question. I'm not a Java guru though, so i couldnt forumlate the equivalent code
It is true that my answer elides over some things, but the underlying point is that there isn't a real comparison available between languages because in Java you should pretty much never need this. Yes, technically you could work yourself into a position where you might need that question answered and have to go through the reflection, but that is truly a last resort, whereas in Python it's sort of the first.
(I say "sort of" because even in Python this is a weird thing; the traditional answer to the question "can I call this as a function" is to simply try it and catch the exception if it fails.)
well of course. Its a last resort in python too. while it's much easier to do in python, its far from idiomatic. It's getting into 'too much magic' territory.
You can't ask this question because you can't not already know the answer.
This isn't true. Here's a trivial scenario for you: a user inputs a URL which represents a web service and a method name. Your code needs to determine if the object which will get returned as JSON by that web service implements the method or not.
There are more complicated examples which occur in actual production systems. For example, suppose you're interfacing with Big Freaking Enterprise code that you can't change, and there is a rule that certain objects have to have certain checks done prior to being sent over the wire. Those checks might be implemented as methods decorated with @FireThisCheckBeforeSendingThisOverTheWire annotations, but that isn't the only way to skin this particular cat. In particular, your million lines of legacy code might have a coding convention where any method starting with "check" gets fired. This worked fine when the code was only running in its own little world and teams of overpaid engineers maintained lists of all the check methods for various classes, but now that code needs to get exposed via a new API to meet some emergent business need, and you want to accomplish this without touching the million line codebase that nobody really understands. Enter the reflection API.
Incidentally, expecting a coding convention like that to actually work isn't totally insane. JUnit 3, I think, treated any method starting with test as a test. I personally prefer it for usability over "slap an annotation on it".
Anyhow, Enterprise Java: abandon all hope ye who enter here.
Here's a trivial scenario for you: a user inputs a URL which represents a web service and a method name. Your code needs to determine if the object which will get returned as JSON by that web service implements the method or not.
You wouldn't do that by reflection, you'd have a mapping between service method names and objects that perform the service. In fact, this sort of thing is pretty typical in web frameworks based on dynamic languages as well. I don't want you calling Object.notifyAll or whatever just by fiddling with urls. Reflection does come up but it's usually in more magical places - serialization (the built-in serialization is an example of interface-by-convention), profilers, debuggers, prototyping tools.
Can I do animal.bark() or animal.fly() ? All I know is that it's an Animal of some sort, may or may not be an instance of the Dog or Bird subclasses of Animal.
This kind of synthetic example is silly, though. The fundamental questions would be the same in Python as well. How did you end up with this heterogeneous collection of objects? Why are you unable to get a collection of objects that are known to support your desired protocol at that point? What happens if they don't? Etc, etc, etc. You might make very different design choices in a statically or dynamically typed language but thinking about zoos and animals with no context isn't particularly informative.
Synthetic? Yes. Contrived? No. I've seen this sort of thing in my own and other people's Java code, where you know what class it is but not the most-derived subclass. That's how polymorphism happens.
Right. It doesn't happen by rooting around objects looking for methods by name. That's usually a sign of some misdesign that's making you re-invent the polymorphic mechanisms of the language yourself. True both in Java and Python.
I agree that polymorphism is the "right way" if there's already a class hierarchy established.
If the superclass-subclass relationships aren't in place for you (worse yet, they're not set up how you want them to be set up), this hack accomplishes a similar effect with no refactoring.
[Disclaimer: I don't read Python, but I think the question here is "Which methods from this list does this object implement?" If I'm wrong please correct me.]
My gut check was this should take about eight lines, plus imports and the class boilerplate. Let's try:
[Edit: It occurs to me the Python code might answer "Does this implement all specified methods?" That also takes eight lines in Java. I've appended the implementation above.]
You can take out another couple if you did a sensible thing like taking a Set<String> as input for method names and returned a Set<String>
But like the other poster said, you're very unlikely to be doing this in Java, making the whole thing take 0 lines and 129.4 fewer insufferable smugness units.
The snippet is imprecise. it should be something like
def hasmethod(obj, meth_name):
"""If it calls like a method it's a method."""
return callable(getattr(obj, meth_name)) if hasattr(obj, meth_name) else False
I don't really care how many lines of Java this takes, if someone commits a garbage scenario like this I'm concerned with how many lines of comments they have explaining why they're doing it instead of solving the problem correctly.
23 comments
[ 1.4 ms ] story [ 52.1 ms ] threadI'm not speaking to whether dynamic/duck typing is good or bad here, just pointing out that the question is flawed.
Java's reflection system exists to answer this question. I'm not a Java guru though, so i couldnt forumlate the equivalent code
(I say "sort of" because even in Python this is a weird thing; the traditional answer to the question "can I call this as a function" is to simply try it and catch the exception if it fails.)
This isn't true. Here's a trivial scenario for you: a user inputs a URL which represents a web service and a method name. Your code needs to determine if the object which will get returned as JSON by that web service implements the method or not.
There are more complicated examples which occur in actual production systems. For example, suppose you're interfacing with Big Freaking Enterprise code that you can't change, and there is a rule that certain objects have to have certain checks done prior to being sent over the wire. Those checks might be implemented as methods decorated with @FireThisCheckBeforeSendingThisOverTheWire annotations, but that isn't the only way to skin this particular cat. In particular, your million lines of legacy code might have a coding convention where any method starting with "check" gets fired. This worked fine when the code was only running in its own little world and teams of overpaid engineers maintained lists of all the check methods for various classes, but now that code needs to get exposed via a new API to meet some emergent business need, and you want to accomplish this without touching the million line codebase that nobody really understands. Enter the reflection API.
Incidentally, expecting a coding convention like that to actually work isn't totally insane. JUnit 3, I think, treated any method starting with test as a test. I personally prefer it for usability over "slap an annotation on it".
Anyhow, Enterprise Java: abandon all hope ye who enter here.
You wouldn't do that by reflection, you'd have a mapping between service method names and objects that perform the service. In fact, this sort of thing is pretty typical in web frameworks based on dynamic languages as well. I don't want you calling Object.notifyAll or whatever just by fiddling with urls. Reflection does come up but it's usually in more magical places - serialization (the built-in serialization is an example of interface-by-convention), profilers, debuggers, prototyping tools.
Animal animal = zoo.getAnimal();
Can I do animal.bark() or animal.fly() ? All I know is that it's an Animal of some sort, may or may not be an instance of the Dog or Bird subclasses of Animal.
If the superclass-subclass relationships aren't in place for you (worse yet, they're not set up how you want them to be set up), this hack accomplishes a similar effect with no refactoring.
Unless the Animal type responds to fly and bark (unlikely in this scenario) that looks like a compile error to me.
My gut check was this should take about eight lines, plus imports and the class boilerplate. Let's try:
http://www.pastie.org/808727
Yep, eight.
[Edit: It occurs to me the Python code might answer "Does this implement all specified methods?" That also takes eight lines in Java. I've appended the implementation above.]
But like the other poster said, you're very unlikely to be doing this in Java, making the whole thing take 0 lines and 129.4 fewer insufferable smugness units.