[futurebasic] Re: [FB] Re: "AS LONG" vs &

Message: < previous - next > : Reply : Subscribe : Cleanse
Home   : April 2001 : Group Archive : Group : All Groups

From: Alain Pastor <apastor@...>
Date: Sat, 14 Apr 2001 18:04:59 +0200

lcs@... wrote:

> Salut Alain,
>
>  > DIM teH AS ..TEREC
>  > DIM teH AS @@TEREC
>  > DIM teH AS HNDL TO TEREC
>
> With ^^TEREC that makes four possibliities. I do like the
> three .., @@, and ^^ because they are compact and easy
> read and write and remember (at least once you understand
> them -- I still don't understand #).  Better, by learning
> about ^ you also learn about ^^, ^^^, and so on. (What
> comes after HNDL? Will I misspell HNDL as HAND next
> week?)
>

Hi Larry,

Actually there are more possibilities than that:
You can use a generic handle (the way FBII used to work)
teH&
teH AS HANDLE
teH AS HNDL
In those cases you need to use the FB predefined constants to access the
pseudo fields whose name, in rare occasions, may differ from the field name
defined in the Toolbox structure. This is what Chris' example has shown with
TEHandle:
top = TEhndl&..teViewRect.Top%
If you want to store the rectangle into a variable (be it declared with DIM
r.8 or DIM r AS RECT), you have to move the 8 bytes explicitly with a variant
of the BLOCKMOVE statement. For instance:
r;8 = @teH&..teViewRect.Top%
Specifying a type for the handle with one of the five following possibilities:

teH AS HANDLE TO TERec
teH AS HNDL TO TERec
teH AS ^^TERec
teH AS ..TERec
teH AS @@TERec
is like saying that you want to parse or analyze the data pointed to by the
handle according to the layout of a given structure. I think of it as a
template applied to an area in memory.
Now this is another story, since the Toolbox structures are correctly defined
by FB^3. They are true records using the field names that you can find in the
Apple Headers. This strategy has some advantages and one of them is that the
field types are known by FB. Consequently, you can write something like this:
r = teH..viewRect
which, in essence, is what you want to do in the first place regardless of the
number of bytes that need to be moved.
Finally, the burden of learning which specific structure must be used in a
given case ends up with code simpler to write, to read and to understand.

As to the # symbol it is not much harder I guess. Some Toolbox calls need to
change the content of variables that are passed in their parameter list. For
this to happen the variable that will be altered and more precisely its
address in memory must be known.
There are circumstances when you have no variable at your disposal to pass
onto the Toolbox call (for instance when you calculate an arbitrary location
in memory using an offset from a known address). Using the # symbol will tell
the Compiler to consider the result of your calculation like if it were the
address of a (fake) variable.

Another common circumstance is when you pass a record onto a LOCAL FN and you
need to send that record to a Toolbox call inside the LOCAL FN.
When you pass a record structure onto a LOCAL FN, FB automatically sends its
address. Notice that it is not required to explicitly pass the address onto
the LOCAL FN with the @ symbol like it was the case in FBII (I think).
Therefore the two following syntaxes work the same:
FN doSomethingWith ( @theRect )
FN doSomethingWith ( theRect )
The incoming parameter, in your LOCAL FN, will be a 4 bytes address that will
be placed into a register (if you have set that preference to on of course).
If you attempt to use the incoming parameter "as is" in a Toolbox call you
will have a couple of difficulties. First, the Compiler will stop quickly
telling you it can't use a register variable with that Toolbox call. But and
secondly, setting the registers to off won't solve the problem. In fact, your
incoming parameter can be seen as an address that FB has calculated for you.
Depending on what you want to achieve, you have then two solutions:

• Copy the data located at that address into a local structure. Ex:

LOCAL FN doSomethingWith (inRectPtr AS ^RECT)
  DIM localRect AS RECT
  localRect = inRectPtr
  CALL InsetRect (localRect, -2,-2)
END FN

There are two important things to note here:

1 - FB magically knows that you want to assign a variable and it moves the
exact amount of bytes in your local structure. I would call it a built-in
shorthand for the following regular statement (which also works perfectly
BTW):
BLOCKMOVE inRectPtr, @localRect, SIZEOF(RECT)
or
localRect;8 = inRectPtr

2 - You are working on a copy of your rectangle, which means that your
original rectangle will be left unchanged once the function has been executed.

• Force the Toolbox call to use the so to speak calculated address that you
have received. Ex:

LOCAL FN doSomethingWith (inRectPtr AS ^RECT)
  CALL InsetRect (#inRectPtr, -2,-2)
END FN

Since you are working on its address, your original structure will be modified
by the function.

Now, what if, for some reasons, you don't want to use the # symbol, but still
want to alter the original structure?
OK, I don't know if it is reliable, but I have discovered that we can pass
back a structure to the calling function doing this:

LOCAL FN doSomethingWith (inRectPtr AS ^RECT)
  DIM localRect AS RECT
  localRect = inRectPtr
  CALL InsetRect (localRect, -2,-2)
END FN = localRect

theRect;8 = FN doSomethingWith ( theRect )

Lately, we had an issue with the SetResInfo Toolbox call. As Heather said some
other calls may be concerned by the trick, so it is a good thing to keep it in
mind. The # symbol can be used to force a nil pointer or a nil handle where a
variable is expected and required. Passing a nil address is not the same as
passing a variable that is null, and it is like saying there is no variable at
all to deal with.

>
>  > It is absolutely unbelievable that we can have both
>  > legacy code and a new enhanced (IMO) way of writing
>  > code living almost in harmony within the same IDE. "Un
>  > v'eritable tour de force" I would say.
>
> Amen.  Indeed it is wonderful.  And necessary.
>
> In an evolving language there will always be a bleeding
> edge.  In a consensus language, particularly one with a
> lot of parttime programmers like me, there must *also* be
> areas of stability and upward compatibility; otherwise
> precious code capital and intellectual capital will be
> bulldozed before it is has paid off.
>
> That's not all, there should be low-level and high-level
> ways of coding.
>
> It's amazing that Staz n Andy manage all these factors
> so well.  It can't hurt to cheer them on!
>

I am close to say that unfortunately you are right. Well, of course I can say
such a thing because I have no critical code to maintain and I believe that
the compatibility issue has put a break on the initial release of FB^3. Given
that one (I for one) can find the new syntax provided by FB far cleaner and
far clearer than what it used to be, one can think that this "necessity" was a
waste of time and currently we should be speaking about FB^3 & MacOS X or FB^3
& OOP rather than comparing the merits of different syntaxes.
Not only that, new features are added to the language with each release. Those
are supposed to make the life easier for the programmers and especially
novices. Of course, there's no point in discussing compatibility if you are
going to use those features. But this stands true if you want to benefit from
many enhancements already included in the language, for instance in the mere
handling of strings. So from my point of view the question about compatibility
would be how can I move smoothly my code to the FB^3 way of doing things
rather than can I still program like FBII with FB^3. This is not always easy
but I strongly believe this is the way to go.
--

Cheers

Alain

-----------------------------------------------------
FB^3 in Europe:  http://euro.futurebasic.com/
FB II Pouch:     http://www.pixmix.com/FB/outils.html
-----------------------------------------------------