develooper Front page | perl.perl5.porters | Postings from May 2000

Re: overloading = [a solution]

Thread Previous | Thread Next
From:
Damian Conway
Date:
May 5, 2000 14:25
Subject:
Re: overloading = [a solution]
Message ID:
200005052125.HAA04720@indy05.csse.monash.edu.au
Some time ago, Jeff Pinyan posted a demo of a handy way of grabbing control
of assignments to variables. I responded that I had a module on that, and
we decided to step outside to discuss it.

Following that discussion I'm now ready to make the module generally
available. There's a summary below. The main question is, should I find
a better name for it? If so, suggestions welcome.

Damian

-----------cut-----------cut-----------cut-----------cut-----------cut----------

NAME
    Class::ifiedVars - Control assignment to scalars

DESCRIPTION
    The Class::ifiedVars module exports a single subroutine named
    `classify', which may be used to associate a particular class name with
    a variable, in order to control the variable's behaviour when assigned to.

    In its simplest form the `classify' subroutine is used like this:

            classify $var => 'ClassName';

    This has two effects. Firstly it enforces *type compatibility* in
    assignments. That is, it restricts subsequent assignments to $var, so
    that only references to objects blessed into class ClassName (or one of
    its derived classes) may be assigned. Attempts to assign an incompatible
    value to $var result in an exception being thrown.

    Secondly, if class ClassName defines (or inherits) a method named
    `ASSIGN', any subsequent assignments to $var:

            $var = $newval;

    will be silently converted to:

            $var->ASSIGN($newval);

    If ClassName doesn't have an `ASSIGN' method, the normal assignment
    semantics are used (always provided, of course, $newval is type
    compatible with $var).


  Type-incompatible assignment semantics

    If you want a variable that delegates assignments to some class's ASSIGN
    method (as above), but that *doesn't* require that the assigned value be
    a compatible type, you can turn off the type-compatibility checking like
    so:

            classify $var => 'ClassName', STRICT => 0;


  Per-variable assignment semantics

    You can also set up a variable with its own unique assignment semantics:

            classify $var => 'ClassName', ASSIGN => $subref;

    where $subref contains a reference to a subroutine.
    Now any assignment to this variable will be converted to:

            $subref->($var,$newval);

    Note that type-compatibility will still be enforced, unless specifically
    disabled:

            classify $var => 'ClassName', ASSIGN => $subref, STRICT => 0;


  Predefining classifiers

    Some applications may require many variables classified identically.

            classify $var1 => 'ClassName', ASSIGN => $subref;
            classify $var2 => 'ClassName', ASSIGN => $subref;
            classify $var3 => 'ClassName', ASSIGN => $subref;
            classify $var4 => 'ClassName', ASSIGN => $subref;
            
            classify $var5 => 'OtherClass', STRICT => 0;
            classify $var6 => 'OtherClass', STRICT => 0;
            classify $var7 => 'OtherClass', STRICT => 0;
            classify $var8 => 'OtherClass', STRICT => 0;

            classify $var9 => 'YetAnotherClass';

    In such cases, it is more efficient to create a single subroutine to do
    this. Class::ifiedVars can optionally export a subroutine named `type'
    that does exactly that. It takes the same arguments as `classify',
    except that, rather than taking a variable as its first argument, `type'
    takes the name of the new local classifier subroutine to be created.

    The subroutine that `type' creates then takes one or more variables and
    classifies them using the same arguments that were originally passed to
    `type'. Hence we could rewrite the above classifications:

            use Class::ifiedVars 'type';

            type Type1 => 'ClassName', ASSIGN => $subref;
            type Type2 => 'OtherClass', STRICT => 0;

            Type1 ($var1, $var2, $var3, $var4);
            Type2 ($var5, $var6, $var7, $var8);

            classify $var9 => 'YetAnotherClass';

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About