I was sitting at my desk yesterday and one of my developers came up to me with a problem with a new interface being developed. Before I get too far ahead of myself, I'll start at the beginning. We are working on enhancing our enum support to use string representations instead of their numeric counterparts. This is beneficial with development environments with WSDL compilation support. You can imagine that it is much more intuitive to represent an availability state of enabled as AVAILABILITY_ENABLED instead of 8. In the current implementation our enum values are returned as type integer for which SOAP::Lite has a deserializer for. But, with the change, we've converted the type be it's iControl defined type (ie. EnabledState is urn:iControl/LocalLB.EnabedState.
...               STATE_ENABLED        
No the problem arises. SOAP::Lite does not know what an element of type "urn:iControl/LocalLB.EnabledState" is and how to deserialize it. After digging through /SOAP/Lite.pm for a while I found the SOAP::Deserializer::typecast method
sub typecast { } # typecast is called for both objects AND scalar types       # check ref of the second parameter (first is the object)       # return undef if you don't want to handle it
Not much is said in the documentation about the typecast method and how to override it, but the comments seem to imply that this is the intended behavior. So in a client app I tested it with the LocalLB.EnabledState enum and came up with the following solution. I added the following code to the beginning of my script:
# Implement typecast for LocalLB.EnabledState elements sub SOAP::Deserializer::typecast {   my ($self, $value, $name, $attrs, $children, $type) = @_;   return ( $type =~ /^{urn:iControl}LocalLB.EnabledState/ ) ? $value : undef; }
This method will get called by the SOAP::Lite deserializer code when it finds an element it doesn't know how to handle. Basically what this does is checks the type for a match of "{urn:iControl}LocalLB.EnabledState" (which is the string representation of the type variable SOAP::Lite generates - {ns}type). If the type matches the given string, the value is returned, otherwise undef which tells the deserializer to continue with processing. This idea can be extended to handle other custom types in your own implementations when using SOAP::Lite from the client. In a future entry I'll talk about creating a custom serializer. Happy coding! -Joe