Hi Tim,


A) Initiliazing Words?
why do you want to initialize the word port to some value before opening
it? Let us assume you did NOT initialize it. Then there are three possible
states for the word port. It does not exist yet, because the port has not
been opened. You can check for this condition using value?

>>  value? 'port
== false

once the word port has been assigned to some value? 'port returns true.
This value could be an open port! or something else. 

Second condition is port has been opened. Third condition is port has been
closed. Note that when a port has been closed, it still qualifies as a
value of type port!. Trying to read from or write to a closed port will
generate an error. (Maybe that is the source of some of your errors? Can
have you been trying to read from or write to a closed port, because the
port was not none?)

3 -> 2

You may want to reduce complexity by dealing with two port states: exists
or open. Then, whenever you close a port, use unset to get rid of the word.
Instead of using the close function, you use the following shut function
that does it for you:

shut: func ['port] [
  if port? get port [
    close get port
    unset port
  ]
]

>> value? 'port
== false
>> port: open %file
>> value? 'port
== true
>> shut port
>> value? 'port
== false


Of course it's more port-like (portly?) to ask the port if its open,
instead of asking it if it exists. Also, if it exists, it better reference
a port! value. Let's do that:

open?: func ['port] [
  return all [
               value? port
               port? get port
             ]
]

>> open? port
== false
>> port: open %file
>> open? port
== true
>> shut port
>> open? port
== false

Using the three functions open?, open, and shut consistently, instead of
using close will narrow words referencing ports to two states. If open?
port returns true, then the word port is pointing at an open port that was
opened using open. If open? port is false, then there is no word port and -
if port previously referenced an open port - then that port has been closed. 

For instance you would say:

if open? port [safe-close port] 

and by having used open? you would be guaranteed that that the port you are
passing to safe-close is an open port, not some other type of value, not a
closed port, and it exists.

3 -> 5?

When you initialize port to some non-port value, you are introducing a
fourth and a fifth state for the word port, in addition to the three
default states. 

Besides being 
1. existent/non-existent
2. open
3. closed

the word port can now also be
4. none
5. a type that is not port!. (namely none!)

1. A function may fail because it expects a port! type value, BUT it is
passed the word port when it references the value none, i.e. a none! type
value. 

2. A function may fail because the having checked for none, it determines
that the value of port is NOT none, and it now attempts to access the port.
BUT the port - even though it is not none - is closed, not open, and
accessing it generates an error message.

My personal preference is to reduce complexity. Two states suits me better
than five.

If I thought that declaring values before using them is important, I would
certainly prefer none over an empty block. A value set to none can easily
be identified using if or either, because none evaluates to a logical false
value. An empty block evaluates to a logical true value. It complicates
matters.

With respect to your example code, be sure to use a uniform function
interface. It does not help you, if you test for the types of arguments
occassionally and not consistently. 

In the following example you note that once you do and once you don't get
an error message. Apparently you overlooked that in one function you are
checking for the type of the argument being passed and in the other version
of the function you do not:

                              argument is type checked here:
                                             |
                                             |
With type checking:    safe-close: func [p[port!]][if p [close p]]

Without type checking: safe-close: func [p][if p <> [] [close p]]
                                         |
                                         |
                               No type checking here

You comment saying:
>>>>>>>>>>>>
lets say  
dufus: none
safe-close dufus
generates
Script Error: safe-close expected p argument of type: port
<<<<<<<<<<<<<<<<

The error message is reporting that your safe-close function is checking
for the type of the passed argument. You require that the argument be of
type port! 
safe-close: func [p [port!]] ...
but you are passing a value of type none!
Therefore you get the error message. You would be getting the same error
message, if you used [] instead of none with this version of the safe-close
function, because you would be passing a value of type block!, while this
version of safe-close expects a value of type port!. block! <> port!

>>>>>>>>>>>
HOWEVER:
if I write 
safe-close: func [p][if p <> [] [close p]]
dufus: []
safe-close dufus
I get no error message.
<<<<<<<<<<

This version of safe-close does NOT test the type of the argument it is
passed:
safe-close: func [p] ...

See, the additional argument type restrictor block - [port!] - is missing
in the interface specification for this version of safe-close. Compare it
to the version used above, where p was followed by a block containing the
type specifier: [port!].  Because this version of the safe-close function
does not check for the type of the argument and does not require that the
type be port!, THEREFORE this version of safe-close does not generate an
error telling you that you passed the wrong type of argument.

It has NOTHING to do with using an empty block instead of none as a word
initializer.



At 05:27 PM 5/23/00 -0800, you wrote:
>Hi Elan:
>; left out the [] !!
>       Perhaps it is better to ask this question:
>What would be the preferred way to initialize a port
>prior to a possible open?
>would it best to be:
>my-port: none
>OR
>my-port: []
>;==========================================================
>>It bothers me, however, that your code fails. The code you present should
>>work as expected, as can easily be tested in the REBOL shell:
>>
>>>> dufus-pointer: none
>>== none
>>>> equal? dufus-pointer none
>>== true
>>
>>I can think of three reasons why this could happen:
>>1. the error is not being generated by the code you presented;
>>2. dufus-pointer is being set (unexepctedly!) to some non-port value
>>somewhere in your program. This possibility should worry you! ;-)
>>3. One of the two none values is not a none value. It is a word value. For
>Your concern is duly noted: If you're worried, I'm worried. 
>Perhaps type? checking is the best way to go....
>regards
>tj
>
>
>
>
>

;- Elan >> [: - )]

Reply via email to