[Date Prev][Date Next][Thread Prev][Thread Next] [Search] [Date Index] [Thread Index]

Re: [MacPerl] Mac::Glue to CodeWarrior IDE?



At 22:33 -0600 2000.11.18, Alex Harper wrote:
>>Chris Nandor pudge@pobox.com wrote:
>
>First off, let me thank you for the quick help...

My pleasure.

And I figured out the problem.  Realize that in Mac::Glue, there are two
separate operations, constructing an object specifier record, and getting
its value.  So you have this:

  $doc = $CW->get($CW->obj(document => whose(name=> equals => "foo.mcp")));
  @targslist = $CW->obj(targets => $doc);

But really need this (see the extra get()):

  $doc = $CW->get($CW->obj(document => whose(name=> equals => "foo.mcp")));
  @targslist = $CW->get($CW->obj(targets => $doc));

Although, I would rewrite it as:

  my $doc = $CW->obj(document => "foo");
  my @targslist = $CW->get($CW->obj(targets => $doc));

That is, you don't necessarily have to have the get() on the first one,
because it just returns a single object specifier record to work on, and
you already have the object specifier record you just created.  But for the
latter, you need the get().  I should have seen that the first time, but it
was late last night and the Bruins were losing to the Wild.  But yes, event
calls return multiple items, but obj() is not an event call, it just
constructs objects to pass to other event calls.



>One question I do have though, is why the previous bad call didn't generate
>an error in $^E?

There was no error to return.  CW just returned an empty reply, saying
"sorry, nothing here matching what you requested."  Now, SOME applications
(like Interarchy) put the error message in the direct reply parameter, and
some put it in the errs/errn parameter.  Only the latter case is picked up
automatically and stuffed into $^E or can trigger your ERRORS handler.  If
I can find a nice way to automatically handle other kinds of errors, I will
add it.



>Certainly... I should mention I haven't seriously worked on this part yet,
>but I was hoping maybe a corrected example of the above stuff would help me
>understand the difference between constructing objects to pass to the get
>call and prop calls to read properties. Your discussion of "of" plus some
>more experimentation has helped me grasp that under the hood Applescript is
>making the difference between the two more-or-less transparent (which is
>apparently not the case with Perl).

Well, they are similar, but the short answer is Yes, you need to be more
aware of what is a property in Mac::Glue than you do in AppleScript.

This doesn't have to remain this way permanently, but for now, it does.  A
big part of this, IIRC, is simply that AppleScript knows at compile time if
something is a class or a property or just a string, and Mac::Glue does
not.  Consider:

   prop(container => of => 'System Folder')     # container of System Folder
   prop(container => container => 'System Folder')
				# container of container "System Folder"

One is asking for the container NAMED "System Folder", and the other is
asking for the container of the System Folder.  The point is that "System
Folder" and System Folder in AppleScript are different (one is a string,
one is a property), but in Perl, they look exactly the same, and so we need
syntactic sugar to differentiate them.



>The CodeWarrior IDE has a call (cut from the Glue pod):
>
>    $obj->make_project([externaleditor => bool])
>        Make the current project (MMPR/Make)
>        Reply type: ErrM
>        Parameters:
>            direct object (----):
>            externaleditor (Errs): Should the contents of the message window
>                  be returned to the caller?
>
>I called this as:
>my @errors = $CW->make_project(externaleditor => 1);
>
>Initially I thought that the reply would be a record which Glue would
>magically transform to a hash I could parse handily. Now I'm beginning to
>understand that what I'm actually going to get is a list of object
>references like (again cut from the glue pod):

The problem here is that Mac::AppleEvents::Simple doesn't know how to
handle this data structure.  But the good news is that you can tell it how.
:-)

sub init {
    $Mac::AppleEvents::Simple::AE_GET{ErrM} = sub {
        $Mac::AppleEvents::Simple::AE_GET{typeAERecord()}->(
            AECoerceDesc($_[0], typeAERecord)
        );
    };
}

Yeah, there should be an easier way to do this, and it would be nice if
somehow we could figure out how to do it automatically.  But the short of
it is that when you do this:

  init();  # just call once at top of script
  my $err = $CW->make_project(externaleditor => 1);

Now $err contains something like:

  $VAR1 = {
          'messagekind' => 'ErGn',
          'message' => 'Unable to load linker for target ³BasicApp Mach-o²
in project ³foo².'
        };


Yay!  Now, if you want to know what ErGn is, you can do a quick lookup:

  $err->{messagekind} = $CW->{IDS}{$err->{messagekind}};

WARNING: The syntax of this is likely changing to (note the ending):

  $err->{messagekind} = $CW->{IDS}{$err->{messagekind}}{name};

And further, it might change again in the future.  I need to really provide
some sort of function to get a name from an ID.  Until then, you can use
this, though.  It will be marked in CHANGES when it does change.  I
envision maybe something like:

  Mac::Glue::get_name($glue, $symbol)

and it would use the lookup table from $glue to get the name for $symbol.

So to make a long story short, you can use this code, with init() from above:

  init();

  my $err = $CW->make_project(externaleditor => 1);
  $err->{messagekind} = $CW->{IDS}{$err->{messagekind}};
  # for when it changes later :)
  $err->{messagekind} = $err->{messagekind}{name} if ref $err->{messagekind};


And once again, we may make this easier to deal with and more automatic in
the future, if I or someone else can think of a better way to do it.

Oh, and for multiple errors, just do my @errs = ... and then loop over the
array to get the data you want:

  my @err = $CW->make_project(externaleditor => 1);
  for my $err (@err) {
    $err->{messagekind} = $CW->{IDS}{$err->{messagekind}};
    $err->{messagekind} = $err->{messagekind}{name} if ref $err->{messagekind};
    print Dumper $err;
  }

And I get:

$VAR1 = {
          'file' => 'FFFF000B2AE5:BasicApp.c',
          'linenumber' => 69,
          'messagekind' => 'compiler_error',
          'message' => '\';\' expected '
        };

$VAR1 = {
          'file' => 'FFFF000B2AE5:BasicApp.c',
          'linenumber' => 70,
          'messagekind' => 'compiler_error',
          'message' => 'undefined identifier \'wRect\' '
        };

...  Wheeeee!

(And, of course, if you want a real path there, you can add a:

  $err->{file} = MacPerl::MakePath($err->{file});

to the loop.)



>Which I can loop over pretty easily in Applescript. Now I understand that
>although I thought this was a record, what I've really got is a object where
>calls like (lineNumber of error) are being automagically turned into
>property reads.

No, it really is a record, I believe.  It's just a record that Mac::Glue
does not know how to parse without some help.  I am not sure offhand how
AppleScript does know.  If I can figure out how AppleScript knows, then I
can probably teach Mac::Glue to know.  Does anyone know?  I might just have
to ponder for awhile.  It might be as simple as "if the return value is a
record of a known class type, coerce it to a regular record, and if a
property in that class is an enumeration, then get the right value
automatically."  This sounds reasonable to me offhand, any input from
others is more than welcome on this (and anything else related to Mac::Glue
:-).  If I did this, you would get the record automatically without the
extra work above.


>Thanks again for you help... And for Mac::Glue. I shudder to think if I was
>trying to do this stuff using the old AppleEvent modules.

Thanks!

-- 
Chris Nandor                      pudge@pobox.com    http://pudge.net/
Open Source Development Network    pudge@osdn.com     http://osdn.com/

# ===== Want to unsubscribe from this list?
# ===== Send mail with body "unsubscribe" to macperl-request@macperl.org