On Wed, 2003-11-05 at 17:09, Chad Fowler wrote: > On Wed, 5 Nov 2003, Simon Kitching wrote: > > # Hi, > # > # I'm porting the Apache Jakarta Commons Digester (written in Java) to > # Ruby at the moment. This module processes xml in a rules-based manner. > # It is particularly useful for handling complex xml configuration files. > # > # However some of the very nice features of this module depend upon being > # able to introspect a class to find what attributes it has, and what > # their datatypes are. > # > # Finding attributes on a Ruby class is simple (just look for "attr=" > # methods). Unfortunately, determining what object types it is valid to > # assign to that attribute is not so simple... > # > I'm not exactly answering your question here, but I'd like to offer some > words of caution... > > Be careful about relying on what "type" of object you've got (I'll > avoiding going into detailed discussion of the fact that "type" and > "class" are not equivalent). An object's class doesn't guarantee much of > anything in Ruby. Javaisms may not apply: Yes. I'm not strictly looking for "the type of the target attribute". As you state, the question "what type *is* the attribute" is something that is usually not worth asking in Ruby. What I'm really looking for is "what type should I convert the string extracted from the xml to before assignment to the attribute". Or, in other words I want to know the name of one type that can validly be assigned to the attribute, so I can generate an instance of that type from the input xml string value. This is slightly different from "what is the type of the attribute", but close enough that Ryan's MetaTags "type annotation" approach will probably work. It can be regarded as a way of giving "type hints". The StrictTyping module is not, I agree, what I want. In fact, the original Digester library has a similar problem when the declared type of an attribute is an abstract type. The Digester library essentially says "well, in that case you can't use the nice convenient SetPropertiesRule api. Use the more explicit (and long-winded) CallMethodRule api instead". Or you can create a BeanInfo class. Unfortunately Java apps face this "lack of target type info" only occasionally, while for Ruby it exists for every attribute.... Whatever syntax is used to indicate "what type should the input be converted to" needs to be clean and concise because it will be used quite a lot to tell xmldigester about how to map xml to object-attributes. > As you can see, any code that that relies on this kind of "type checking" > in Ruby is naive. Worse than that, the desire to shoe-horn > Ruby into Java-like "strictness" can blind the user into missing the > point, and therefore the full benefit, of what Ruby has to offer. Yep. I can't see how to offer what I want without some type info, though. If you look at my original example, how to I know that item.cost = '3.50' is wrong (the instance will eventually trigger some error), and item.cost = '3.50'.to_f is the right thing to do? With Java it just happens magically and "does the right thing" (except in the abstract type case mentioned above). Surely Ruby can't be inferior :-). > > As I said, I haven't actually addressed your problem here. If it were me, > I would be looking for (or writing) something that generates code based on > an XML Schema. One of the xmldigester goals is *not* to require an XML Schema. There are "code generation" approaches that do this. In many circumstances they are a good solution However in many cases they are also a bad solution. The original Digester fills this ecological niche nicely in Java. I hope xmldigester will fill the same niche in Ruby. But that depends upon finding a reasonable solution to this type-of-attribute problem that leaves the library reasonably easy to use. And I'm not sure that the XML Schema approach works that well either. Yes, it can document the "type" of the data "in" the xml. But does that always match with the datatype you want to pass to an attribute? I'll think about this a bit, though. However if I do go down this road, I'll have to change the project name as it will be quite different from the Apache Digester ;-) > What you're really looking for is convenience (as opposed > to "type safety"). Yep. Absolutely. > You want to be able to add 1 + 1 and not end up with 11. Or go item.cost = some_value and not have an exception thrown later when the class goes to use cost in some arithmetic operation. > You could easily accomplish this via some tedious coding or you could > generate the tedious code. By tedious, I mean things like this: > > class Person > def age=(how_old) > @age = Integer(how_old) > end > end Yep. Tedious indeed. And as mentioned in my reply to Austin, it is a goal to instantiate and initialise objects without requiring any changes to their code. Digester manages this fine. > > Ruby being as dynamic as it is, it would be pretty easy to dream up a > scheme to wrap existing classes with filters that could do this kind of > conversion for you. And, of course, you could generate the filters. The problem is : in order to automatically generate the filters, I need to know what type of object is required for each attribute. Full circle! That code in the Person class you show above could only be generated because a human "knew" that Integer was an appropriate type to store into the age attribute (and String was not). I just want to represent that info in the code somehow... > And now, the cold medication sets in.... That may have been more information than I needed to know :-) > > > Good night, > Chad > Good afternoon... Simon