Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion Groups
General
GeneralPortable MacsHardwareNetworking
Applications
Mac ApplicationsEudoraFirefox / MozillaInternet ExplorerOutlook ExpressMS OfficeEntourageExcelPowerPointWordVirtual PCMedia PlayerOther MS Products
Programming
Mac ProgrammingCodeWarriorPerl
Country Specific
Australian Mac GroupUK Mac Group

Mac Forum / Programming / Perl / January 2006



Tip: Looking for answers? Try searching our database.

Foundation in Perl script

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Manfred Bergmann - 29 Dec 2005 00:05 GMT
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
Sherm Pendley - 29 Dec 2005 01:34 GMT
> 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
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.