Thoughts on a Ctypes::Type object API
For the past few days I've been considering and experimenting with the design of simple Ctypes::Type objects. These are objects which, funnily enough, represent C data types for manipulation in Perl.
The reference implementation
Looking at the Python ctypes module, there were various things I didn't like. Python's simple types  can be summarized thusly:
>>> i = c_int(42) >>> print i c_long(42) >>> print i.value 42 >>> i.value = -99 >>> print i.value -99 >>>
Having to specify
i.valueseemed cumbersome for an object which essentially represents just that value and some rules for what kinds of values it can contain. So I started trying various things with
overloading. Indeed, I was about to start a fourth project branch on types  before reigning in and having another think about fundamental behaviour.
The 'Metaphor Clash' section  of perldoc
overload made clear the difficulty I was having with my thinking. If you want to be able to say simply,
$int_obj = 42; # assign new value to Ctypes::Type::c_int object
and not have $int_obj smushed and replaced by a simple IV, you're forced to do something like,
$other_obj = $int_obj->copy();
on those occasions when that's the outcome you really want. That might not be regular for objects in Perl, but I think that this is more suitable in this domain, where as I mentioned before, objects are just there to represent special kinds of values. Particularly, it would let you do this:
$c_int = $c_long; # Put long value into integer type, with # appropriate checking on STORE
rather than having to say
$c_int->val = $c_long->val;
I think that once you've instantiated a Ctypes::Type object, what you're going to be doing 90% of the time is assigning values to it or assigning its value to other things. The times when you want to squash the object with a different object or value, instead of just creating a new one, will be rare, and there can be special methods for doing those things.
What do you think? Is this a reasonable generalisation to make? How would you like Type objects to work?
Other issuesThere are a couple of other issues tangential to this which I'd like to flag up while we're at it...
- The latter behaviour, while IMO preferable, will I think be harder to implement. I haven't yet found a way using only Perl to hide the process of
tie'ing a variable from the user. This is horrible:
my $int = 5; # regular scalar c_int(\$int); # make it a Ctypes::Type
but it's one of the only ways to enable the assignment of new values to the object without using an accessor every time (the other way is returning a reference from
c_int()and requiring users to say
$$intall the time). I think the desired effect would be possible, but
c_int()will have to be written in XS. That's fine, but I want to sound out opinions on whether I'm making the right choices on functionality first.
- The latter behaviour, while IMO better than that in Python's ctypes, may represent a significant difference from the de facto 'conventional' way of doing things. This raises a bunch of issues to be addressed in a subsequent post.
Please do let me know what you think of the above proposals. I'm highly suggestible.