[comp.sys.mac.hypercard] evalExpr

pbiron@weber.ucsd.edu (Paul Biron) (07/08/90)

Hi all,

A while back I asked if there was a way to tell if an
arbitrary object existed (e.g. if Exists (cd fld "foo") then ...).

Numerous people pointed me to the Dartmouth XCMDs (vol 3)
available from sumex.  Well, I finally got them (thanx
to all who helped with that), and eagerly jumped into
the source for ObjectExists().

What I found has the rather simple :

	paramBlock^.returnVal =
		EvalExpr (CONCAT ('the name of '), paramBlock^.params[1]) ;

(or the equivalent, I don't have the code in front of
me at the moment).

Why is it that this works in an XCMD and not in a script
or from the message box?  In a script or from the msg
any reference to a non-existant object results in a

	Never heard of ...

error box (even in HC 1.2.2).

In all the references I own (or have looked at) the
description of the EvalExpr() callback is that it does
the same thing that would happen if its argument were
typed in the msg.

In the same vein, why is it that something like

	go card foo   (where foo is a non-existant card)

when typed into the msg will produce the above "Never..."
error box, yet when in a script no such error occurs?

Anybody know of anything else which works differently
when typed in the Msg or called from a script (except
for 'if', 'then', 'repeat', etc which are documented
to *NOT* work when typed in the Msg)?

Any help will be greatly appreciated.


Paul Biron      pbiron@ucsd.edu        (619) 534-5758
Central University Library, Mail Code C-075-R
Social Sciences DataBase Project
University of California, San Diego, La Jolla, Ca. 92093

taylorj@yvax.byu.edu (07/10/90)

In article <2608@network.ucsd.edu>, pbiron@weber.ucsd.edu (Paul Biron) asks
why using EvalExpr for the Exists function in the Dartmouth collection
works from the XFCN but not from HyperCard.

The difference is that X-commands have error results returned to them, as
opposed to an error dialog popping up.  This is so that the X-command can
handle the error appropriately without bothering the user.  The writer of
the Exists XFCN brilliantly took advantage of this.

The "go to non-existant card" thing works the same way.  An error message is
returned in "the result" instead of a dialog popping up so that a script
can handle things without user intervention.


Jim Taylor
Microcomputer Support for Curriculum   |
Brigham Young University               |   Bitnet: taylorj@byuvax.bitnet
101 HRCB, Provo, UT  84602             |   Internet: taylorj@yvax.byu.edu

stm@apple.com (Steve Maller) (07/10/90)

In article <2608@network.ucsd.edu> pbiron@weber.ucsd.edu (Paul Biron) 
writes:
> A while back I asked if there was a way to tell if an
> arbitrary object existed (e.g. if Exists (cd fld "foo") then ...).

HyperCard 2.0 contains a HyperTalk function called "there is a". For 
example, you can say
  if there is a card button id 4
  if there is a file "MyDisk:Fred"
  if there is a window "Variable Watcher"
Obviates the need for any more such monkeying around...

Steve Maller
Software Engineer
Apple Computer

I yam what I yam...

spector@brillig.umd.edu (Lee Spector) (07/10/90)

In article <1388taylorj@yvax.byu.edu> taylorj@yvax.byu.edu writes:
>
>... X-commands have error results returned to them, as
>opposed to an error dialog popping up.  This is so that the X-command can
>handle the error appropriately without bothering the user.  

Hmm... This should allow the creation of a WithoutError XCMD which would
evaluate an arbitrary line of hypertalk (WITHIN HC) without the possibility 
of an error  reaching the user.  Any returned error message could be stuffed 
into a global variable or something.   This would allow something like:
  
  ...
  WithoutError "myCommand (myfunction1 (foo))"
  if the result contains "Error" then  -- or however you test the result
    put "something went wrong but I don't care"
  end if
  ...

I imagine that this could be useful in a number of situations.  For example
it would be handy when consing together code for "do" on the fly; it would 
be nice to be able to allow gibberish through once in a while and to just 
have it do nothing...  Anyway, has anyone done this?  If so, can I have a 
copy?   

  Thanks!

 -Lee (spector@cs.umd.edu)

pbiron@weber.ucsd.edu (Paul Biron) (07/10/90)

In article <1388taylorj@yvax.byu.edu> taylorj@yvax.byu.edu writes:
>In article <2608@network.ucsd.edu>, pbiron@weber.ucsd.edu (Paul Biron) asks
>>why using EvalExpr for the Exists function in the Dartmouth collection
>>works from the XFCN but not from HyperCard.
>
>The difference is that X-commands have error results returned to them, as
>opposed to an error dialog popping up.  This is so that the X-command can
>handle the error appropriately without bothering the user.  The writer of
>the Exists XFCN brilliantly took advantage of this.
>
>The "go to non-existant card" thing works the same way.  An error message is
>returned in "the result" instead of a dialog popping up so that a script
>can handle things without user intervention.
>
>Jim Taylor
>Microcomputer Support for Curriculum   |
>Brigham Young University               |   Bitnet: taylorj@byuvax.bitnet
>101 HRCB, Provo, UT  84602             |   Internet: taylorj@yvax.byu.edu


It would be nice if it were this simple; however, it is not!

The behavior you describe does happen with references to
non-existent *CARDS*, but not with *ANY* other kind of object
(e.g. buttons or fields).  My initial need for the ObjectExists()
XCMD was a case where I needed to know whether a certain
named *BUTTON* existed.

In the case of reference to a non-existent *BUTTON* [from the
MsgBox or from a script but *NOT* thru a callback with EvalExpr()]
an error dialog is called up!!!!

Perhaps Winkler et. al. had intended to make the behavior
the same for cards, buttons, fields, etc but they did not.

Again, does anyone (perhaps someone from Apple) have any
explanation for why this is so?


Paul Biron      pbiron@ucsd.edu        (619) 534-5758
Central University Library, Mail Code C-075-R
Social Sciences DataBase Project
University of California, San Diego, La Jolla, Ca. 92093

jkc@Apple.COM (John Kevin Calhoun) (07/12/90)

The ObjectExists XFCN works with all objects, as long as you're using
HyperCard 1.2 or later.  But, as Steve Maller already pointed out,
you don't need it anymore in 2.0...

Kevin Calhoun
Software Engineer
Apple Computer

KOFOID@cc.utah.edu (08/31/90)

Dan Winkler's callback routine "evalExpr" is described as doing the 
following: "Evaluate[s] a HyperCard expression and return[s] the answer. 
The answer is a handle to a zero-terminated string". I find that it also 
evaluates local variables within the handler calling the external. This 
really isn't surprising, as a a lone variable is the simplest form of an 
expression. 

What I can't get it to do is to evaluate any expression querying the 
number or nature of the parameter list passed into the embracing handler. 
Thus, if I have an XFCN, theVal, which evaluates the expression passed to 
it as a parameter and then returns its value, the following will not work:

    on foo item1,item2             |       When called as:
      put theVal("item1")          |         ...
    end foo                        |         foo 2, "foobar"
                                   |         ...
                                   |       it writes garbage.

evalExpr will also not properly evaluate the functions "param(0)", 
"param(<any positive number>)", "paramCount()" or "params()".

On the other hand, the following works just fine:

    on foo item1,item2             |       When called as:
      put "dill pickle" into item1 |         ...
      put theVal("item1")          |         foo 2, "foobar"
    end foo                        |         ...
                                   |       it writes "dill pickle"..


What I really want is to tell the external the number of parameters 
passed to the handler in which it is embedded. Does anyone have any ideas 
how this could be done?

Another, far more difficult question. Can anyone think of a way by which 
the XCMD can learn the symbol *name* passed as a parameter to the 
handler? That is, given an external similar to the previous examples, and 
the following code:

    ...
    put 1438 into appleNum
    foo appleNum, bar
    ...

..is there any way by which theVal can report the symbol name "appleNum" 
in addition to its value, 1438?

Shades of self-modifying code! Not to worry: I'm trying to fake 
parameter-passing by reference. I have an XCMD which emulates pseudo-var 
parameters, but it places inelegant burdens on the programmer. 

I want to enable the easy creation of libraries of modular code, 
adaptable to a variety of scripting requirements. This can only be done 
by avoiding globals. One route is a Lisp-like solution, returning lists 
by XFCNs, and parsing them for the required values. The other is the 
Pascal-like method of modifying the actual parameter passed when it is 
declared modifiable. I have chosen the latter, as it is easier (although 
it introduces side-effects).

I would be interested in comments from anybody.

Cheers,

Eric.

 __________________________________________________________________
|       Eric Kofoid; Dept. Biology, U. of Utah; SLC, UT 84112      |
|                          (801) 581-3592                          |
|                     kofoid@bioscience.utah.edu                   |
|                                                                  |
| -- The University of Utah is blameless for anything I've said -- |
|__________________________________________________________________|