TIP 519: Inline export/unexport option to TclOO method definition

Login
Author:       Pietro Cerutti <gahr@gahr.ch>
State:        Final
Type:         Project
Vote:         Done
Created:      18-Oct-2018
Post-History:
Tcl-Version:  8.7
Keywords:     TclOO
Tcl-Branch:   tip-519
Vote-Summary:   Accepted 4/0/2
Votes-For:      DKF, KBK, JN, SL
Votes-Against:  none
Votes-Present:  BG, FV

Abstract

This TIP proposes a way to declare a TclOO method's visibility at definition time.

Rationale

TclOO methods are either exported or unexported. By default, methods which name starts with a lower case letter are exported. It is possible to override the default behaviour by a separate call to export or unexport at class definition time. However, this separates the method definition from its visibility declaration.

As an example, consider the definition of a class representing an RPC client to some remote server. The operation of instances of this class is controlled by a number of per-instance settings.

oo::class create RPCClient {
    variable async ;# Send requests asynchronously
    variable debug ;# Log requests and response
    variable cache ;# Keep a cache of the responses to MRU requests
    variable tls   ;# Encrypt the connection using TLS
}

Settings can be turned on and off. Additionally, their current true-ness can be queried. A pattern to expose setters/getters for these settings would be as follows:

oo::define RPCClient {

    method +async { set async 1 }
    method -async { set async 0 }
    method ?async { set async   }
    export +async -async ?async

    method +debug { set debug 1 }
    method -debug { set debug 0 }
    method ?debug { set debug   }
    export +debug -debug ?debug

    method +cache { set cache 1 }
    method -cache { set cache 0 }
    method ?cache { set cache   }
    export +cache -cache ?cache

    method +tls { set tls 1 }
    method -tls { set tls 0 }
    method ?tls { set tls   }
    export +tls -tls ?tls
}

Proposal

This TIP proposes to extend the method subcommand of the oo::define command to accept an optional argument to specify its visilibity inline.

* method name ?option? argList bodyScript

Where option can be either -export or -unexport. If no option is provided, the default applies.

This change is backwards-compatible, as the new form is not currently valid and would result in an wrong-number-of-arguments error.

The class definition in the previous example would then be as follows:

oo::define RPCClient {

    method +async -export { set async 1 }
    method -async -export { set async 0 }
    method ?async -export { set async   }

    method +debug -export { set debug 1 }
    method -debug -export { set debug 0 }
    method ?debug -export { set debug   }

    method +cache -export { set cache 1 }
    method -cache -export { set cache 0 }
    method ?cache -export { set cache   }

    method +tls -export { set tls 1 }
    method -tls -export { set tls 0 }
    method ?tls -export { set tls   }
}

Implementation

See the tip-519 branch.

Copyright

This document has been placed in the public domain.