Determining whether an object has some method or property
Posted: November 17th, 2010 | Author: Mars | Filed under: Design | 2 Comments »- Ruby:
has = foo.respond_to?('bar') - Python:
has = getattr(foo, "bar", None) - JavaScript:
has = foo.hasOwnProperty('bar') - PHP:
has = method_exists($foo, "bar"); - Perl:
has = $foo->can("bar"); - C#:
has = foo.GetType().GetMethod("bar") != null;
This is also possible in Java, using the reflection API, which is so verbose that I refuse to waste time typing out an example. I don’t know whether Scala or Clojure has better syntax than Java does, but presumably they can at least use the same API.
At least ‘bar’ is always quoted.
I think even that may end up being different in Radian! Methods are indexed as symbols, not as strings, and there is (intentionally) no way to convert between the two at run time. You’d have to specify a symbol literal rather than a string literal, or I’d have to add some fancy new operator that captures an identifier as a symbol value instead of evaluating it as an expression (which is what the member-access operator does).
I think I may end up implementing a new operator which calls the LHS as an indexed container, passing in the RHS, and testing to see whether the result is exceptional. If not, the container has an element with the desired key. This way it would work for objects, tuples, arrays, maps, sets, and all the rest.
I see two basic philosophies in the examples above: you can either ask the object whether it has such-and-such a method, or you can use reflection to get information about the method and then ask whether you got anything or not. Radian has no classes and very little in the way of metadata, which pushes me toward the former style.
Borrowing Scheme’s symbol literal syntax for the moment, I think the Radian version might look like this:
if foo has 'bar: