Here's the deal: In CB 0.2, the information provided by method
attributes (Selector, ArgTypes & ReturnType), is stored in a package
hash %OBJC_EXPORT. It is fetched and used later, when the method is
called. In 0.3, the information is used much earlier, when registering
the class with the Objective-C runtime. I had first planned to put the
class registration code in CamelBones.pm's import() function, making it
completely invisible.
But that idea didn't pan out. It seems that import() is called before
any attribute handlers in the use()ing package are called. To put it
another way, %OBJC_EXPORT hasn't yet been populated when import() is
called, so we can't put the class registration code in import().
What's left is a class registration function. The code within this
function basically exists already, as parts of the import() and
outlet() functions. What's left is to design the interface for it - and
because that will have a major impact on the code that you all write, I
thought I'd ask for opinions about it. What I'm currently thinking is
something like this:
package MyClass;
use CamelBones qw(:All);
# This is the registration function
class MyClass, {
super => 'NSObject', # This would be optional, defaulting to
'NSObject'
# In addition to registering properly with the runtime, this
would also
# create @ISA if necessary, or add the class to an existing @ISA.
properties => { # As shown here, properties could have either a
"simple"
# or an "extended" declaration.
'foo' => 'NSSomething', # Simple, with type-checking enabled in
setter method.
'bar' => undef, # Simple, no type-checking
'baz' => { # Extended
'type' => 'NSSomething', # Optional, default to NSObject. If
specified, type-checking is
# performed in setter method.
'derived_from' => [ # Optional. This would work with Cocoa
Bindings, aka KVO.
'foo', 'bar' ], # When 'foo' or 'bar' changes, observers would
also be notified
# that 'baz' has changed.
},
},
};
For property lists where *all* of the properties would use the "simple"
form without type-checking, "properties" could be declared as an array
ref rather than a hash ref:
class MyClass, {
properties => [ 'foo', 'bar', 'baz' ],
};
For trivial classes that subclass NSObject and have no properties, the
hash could be omitted:
class TrivialClass;
The declared class isn't required to match the package name. This can
be useful, for example, in extending existing classes by adding new
methods:
package MyNSStringExtensions;
use CamelBones qw(:All);
class NSString;
Note that in the case of extending an existing class, the super class
is already determined and can't be changed, and the Objective-C runtime
doesn't allow any new properties to be added. So none of the options
available to the two-argument form could be used.
Comments, anyone?
sherm--
Cocoa programming in Perl: http://camelbones.sourceforge.net
Hire me! My resume: http://www.dot-app.org
|