Hi list.
I want to use some Foundation objects like NSDictionary and others in
a Perl script (because of writing a plist of that).
I succeeded with using PerlObjCBridge (use Foundation).
Is this possible with CamelBones, too? Sherm?
Thx,
Manfred
> I want to use some Foundation objects like NSDictionary and others
> in a Perl script (because of writing a plist of that).
> I succeeded with using PerlObjCBridge (use Foundation).
>
> Is this possible with CamelBones, too? Sherm?
Yes, it is. When you install CamelBones, it installs a "embedded"
framework and Perl module in /Developer/CamelBones; that's the one
that gets copied into .app bundles for GUI apps. It also installs a
"shared" framework in /Library/Frameworks, and a Perl module that
uses that framework under /Library/Perl, so you can use those from
standalone .pl scripts.
Because a .pl file isn't a bundle, you can't package it up with an
embedded copy of the framework. If other people want to use your
script, they'll need to install the CamelBones package.
CamelBones and PerlObjCBridge are very similar, but there are some
differences.
CamelBones supports subclassing of Cocoa classes.
Cocoa exceptions in CamelBones are caught with an eval {} block.
PerlObjCBridge handles exceptions with a callback function.
CamelBones has support for toll-free bridging. If you call a method
in scalar context that returns an NSDictionary or NSArray, you get an
object returned. But, if you call it in list context, you get a tied
hash or array instead. So you can use "for (keys %foo)" instead of
NSEnumerator to access the elements of an NSDictionary, for instance.
The toll-free bridging works the other way too - you can pass an
array or hash ref wherever an NSArray or NSDictionary is expected.
NSPoint, NSRange, NSRect, and NSSize structs can also be passed as
array or hash refs.
With CamelBones, the trailing underscore when you call Cocoa methods
that take one or more arguments is optional. So you could write
either $object->doFoo_($bar) or $object->doFoo($bar). PerlObjCBridge
requires the trailing underscore.
Of course, there's this:
use CamelBones qw(:All); # Or qw(:Foundation) if you don't want
AppKit imports
vs. this:
use PerlObjCBridge;
sherm--
Cocoa programming in Perl: http://camelbones.sourceforge.net
Hire me! My resume: http://www.dot-app.org
Manfred Bergmann - 29 Dec 2005 02:09 GMT
Thx. That works like a charm.
The toll-free bridge also includes something like this?
my $str = NSString->stringWithString("astring");
where with PerlObjCBridge you have to use this:
my $str = NSString->stringWithCString_("astring");
Best regards,
Manfred
Am 29.12.2005 um 12:34 schrieb Sherm Pendley:
>> I want to use some Foundation objects like NSDictionary and others
>> in a Perl script (because of writing a plist of that).
[quoted text clipped - 48 lines]
> Cocoa programming in Perl: http://camelbones.sourceforge.net
> Hire me! My resume: http://www.dot-app.org
Sherm Pendley - 01 Jan 2006 18:03 GMT
> The toll-free bridge also includes something like this?
> my $str = NSString->stringWithString("astring");
>
> where with PerlObjCBridge you have to use this:
> my $str = NSString->stringWithCString_("astring");
Yes - strings are bridged both ways. Although, tied objects aren't
passed or returned, just copies. Because Perl's "native" string-
handling is generally more useful from within Perl scripts than
NSString's methods, the default for methods that return NSString
objects is to return them as string scalars. So the $str in the above
wouldn't be a blessed NSString object reference, just an ordinary
scalar.
You can get NSString objects if you want, by setting
$CamelBones::ReturnStringsAsObjects to a non-zero value. You can use
local() to localize the change, like this:
my $str;
{
local $CamelBones::ReturnStringsAsObjects = 1;
$str = NSString->stringWithString("aString");
# $str is an NSString object
}
# After the local() above falls out of scope, ReturnStringsAsObjects
reverts back to its
# old value. So, this method returns a scalar string, not an object.
print $str->uppercaseString();
sherm--
Cocoa programming in Perl: http://camelbones.sourceforge.net
Hire me! My resume: http://www.dot-app.org
James Harvard - 03 Jan 2006 12:16 GMT
I'm building a script that uses a sub-routine for user-interaction:
if ( &ask('Do you want to do this?') ) {
# do stuff
}
I'd like to have a switch variable that allows me to toggle the user-interaction mode. In other words, if $interact is false then ask() will not prompt the user and will return true.
I see that Perl does not complain if I do this ...
my $interact = 0;
sub ask {
return 1 unless $interact;
# otherwise do user-prompt stuff
}
... but is that considered bad programming practice? It seems like unnecessary extra typing to pass $interact as an argument to the sub-routine every time, or to always do "if ( (! $interact) || &ask )".
Many TIA,
James Harvard
Wren Ng Thornton - 03 Jan 2006 13:14 GMT
IMHO that's not bad programming practice. If ask() is
supposed to always or never ask the user, then it
makes sense to have ask() deal with whether it should
do so or not. If you want some sort of mixture, i.e.
ask some things all the time regardless, then it's
probably not the best approach.
The potential of good/bad practice would have more to
do with using a global vs passing it in all the time.
Again, if it's *always* passed in, then it makes some
sense to make it global (or a field in the calling
object if you're using OOP). At the same time, it's
good practice to avoid globals whenever possible since
they lead to unforeseen interactions, spaghetti code,
and the like. How important avoiding them is depends
on the project in question: smaller projects (which
are not anticipated to grow substantially) are more
forgiving about allowing them.
Of course depending on the project, you could just ask
inline rather than hiding code in a subroutine.
Granted that you're not calling ask() more than once,
natch.

Signature
Live well,
~wren
__________________________________________
Yahoo! DSL Something to write home about.
Just $16.99/mo. or less.
dsl.yahoo.com
Ken Williams - 03 Jan 2006 16:23 GMT
It's fine if you think it's fine, but it might get difficult to manage
in a large codebase. An alternative with more encapsulation would be
this:
{
my $interact = 0;
sub interact { $interact }
}
sub ask {
return 1 unless interact();
# otherwise do user-prompt stuff
}
-Ken
> I'm building a script that uses a sub-routine for user-interaction:
>
[quoted text clipped - 19 lines]
> sub-routine every time, or to always do "if ( (! $interact) || &ask
> )".
> Many TIA,
> James Harvard
Sherm Pendley - 03 Jan 2006 20:44 GMT
> I'm building a script that uses a sub-routine for user-interaction:
>
> if ( &ask('Do you want to do this?') ) {
> # do stuff
> }
In addition to the points other folks have made, I should point out
that using & to call subroutines is a bad idea, unless you know
exactly what it does and you really want to do that. The normal "best
practice" way to write the above would be:
if ( ask('Do you want to do this?') ) {
# do stuff
}
For details, have a look at "perldoc perlsub", especially the
"Prototypes" section.
sherm--
Cocoa programming in Perl: http://camelbones.sourceforge.net
Hire me! My resume: http://www.dot-app.org
Doug Wiebe - 03 Jan 2006 17:10 GMT
my $str = NSString->stringWithString_("astring");
does work with PerlObjCBridge. In general, if an Objective-C method
expects an object and you pass a Perl string, PerlObjCBridge
autoconverts the Perl string to an NSString.
NSString return values are not autoconverted to Perl strings, by
design. There are valid arguments either way. It is easy, of
course, to get the Perl string by appending "->cString()" to the
method invocation or return value.
PerlObjCBridge does not do the other kinds of autoconversion that
CamelBones does. It does provide functions to convert back and forth
between plists and Perl structures. See Foundation.pm or the
PerlObjCBridge man page.
- Doug
> Thx. That works like a charm.
>
[quoted text clipped - 61 lines]
>> Cocoa programming in Perl: http://camelbones.sourceforge.net
>> Hire me! My resume: http://www.dot-app.org