The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Class::MakeMethods::ToDo - Ideas, problems, and suggestions

SYNOPSIS

There are lots of things that could be done to improve this module.

DISTRIBUTION ISSUES

Issues about the distribution and supporting files, rather than the code:

Package Name

To date, this module has been circulated under several provisional names: it was originally floated as a possible version-2 rewrite of Class::MethodMaker, then renamed to Class::Methods when it forked from that project, and then briefly to Class::MethodGenerator.

It can be surprisingly difficult to comply with both of these perlmodlib guidelines:

  To be portable each component of a module name should be limited
  to 11 characters.
  
  Always try to use two or more whole words. 

A few minutes with a thesaurus, and an inquiry on comp.lang.perl.modules, produced the following candidates: Class::MethodGen, Class::MetaMethods, Class::AutoMethods, Class::DeclareSubs, Class::SubMaker, Class::CodeLibrary, Class::MethodKit, Class::MethodMill, Class::MethodSmith.

For now, I've selected Class::MakeMethods, as it is two whole words, and is reminiscent of Class::MethodMaker without being confusing. (I hope!)

Other suggestions or approaches to this problem would be welcome.

Documentation

  • Make sure that the documentation is broken up into appropriately-sized chunks, and that people will know which section to look at.

  • As user questions arrive, add them to a FAQ section in the Guide.

  • Assemble annotated examples and tutorials, and either link to or distribute them.

Tests

  • Expunge old custom Test module in favor of standard version, except for emulation compatibility tests, which should remain untouched.

  • Use Devel::Coverage to measure test coverage, and fill in missing cases.

ISSUES FOR ALL SUBCLASSES

  • For scalar methods (and perhaps others) it would be nice to have a simple bounds-checking interface to approve or reject new values that were passed in.

    As pointed out by Terrence Monroe Brannon, the right interface to adopt is that of Attribute::Types:

      use Class::MakeMethods::Template::Hash (
        'scalar' => [ 'count' => { TYPE => 'INTEGER' } ],
        'scalar' => [ 'name' => { TYPE => qr/^[A-Z]\w*$/ } ],
        'scalar' => [ 'account' => { TYPE => &checksum_account_number } ]
      );
  • Add AUTOLOAD support for clients who wish to have accessors lazily built for them when they use them.

      sub AUTOLOAD {
        (my $func = $AUTOLOAD) =~ s/^.*::(_?)//;
        Class::MakeMethods->make( ... => [ $func,... ] );
        if ( my $sub = $1->can( $func ) {
          goto $sub( @_ );
        } else {
          croak sprintf q{Can't locate object method "%s" via package "%s"}, $func, ref( $_[0]);
        }
      }
  • Figure out which modules, if any, should actually be using AutoLoader. Perhaps just Template::Generic?

  • Improve use of _diagnostic hooks for debugging. Add various "(Q)" diagnostics.

  • x

    Can we compile the various closure generators as named subroutines, and then get a reference to them or call them by name, such that debugging output shows something more helpful than ANON?

    No -- It doesn't look like there's a way to do this. Naming the closure-generator doesn't provide a name to the closure.

STANDARD AND COMPOSITE CLASSES

  • Finish tests for Standard modules.

  • Finish building Inheritable array and object accessors.

    Factor out common code from Standard::Inheritable and Composite::Inheritable.

  • Finish building and testing of Composite::* packages.

  • Resolve DESTROY-time issues with Standard::Inheritable, Composite::Inheritable, and Template::Flyweight.

  • Add slice and splice functionality to Standard::*:hash and Composite::*:hash.

  • Rename Basic::Static to Basic::Global, or rename other ::Global module to Static.

TEMPLATE CLASSES

The following issues apply to Class::MakeMethods::Template and its subclasses.

Most important: Need to fix initialization behavior to properly search up the inheritance hierarchy, so that you don't have to redclare methods in each Generic subclass to get your class expressions.

Documentation

  • Finish overhauling Template documentation.

  • Include Static and Flyweight uses in the EXAMPLES section

  • Template Internals: Finish documenting the Template mechanism.

  • Template Internals: Finish documenting disk-based meta-method code-caching.

Template::Generic

  • Make instance a template of object.

  • Allow untyped object accesors if class attribute is not set. (Suggested in Jan-01 NY Perl Seminar discussion.)

  • Standardize naming templates for array, hash, other method types.

    Deprecate verb_x methods? Or at last make them consistently available both ways.

    Make list methods consistent with hash_of_lists methods, in action, and in name (x_verb). Also for others (e.g., set_ clear_ boolean)

  • Should default object template provide auto-create behavior on ->get()?

  • Figure out how to standardize the "Generic:scalar -init_and_get" interface to support memoizing values for other types.

  • Consider adding hash each and array iterator methods, using a closure to provide iteration.

  • !

    Add support for tied arrays & scalars, a la tiedhash

  • Add string_multiple_index.

  • Extend index methods to support weak indexes with WeakRef. Perhaps just have it accept a hash ref to use as the index, and then allow people to pass in tied hashes?

  • *?

    Provide lvalue subs as alternative to get_set:

       sub foo : lvalue { 
           my $self = shift;
           $self->{foo};
       }
  • *?

    Make private or protected method croak if they were called by a method_init method which was called by an outside package.

    Not entirely clear what the right semantics are here...

Template::Generic Subclasses

  • Finish building code_or_scalar meta-method.

  • Finish building Class::MakeMethods::ClassInherit subclass.

    Need to work out how to capture changes for non-scalar values. For example, if a subclass inherits an array accessor and then pops it, do they get copy-on-write?

  • Finish building PseudoHash subclass.

    Use %FIELDS rather than array of slot names.

  • Add enumerated string/number type.

    Provide helper methods with map of associated values (ex $o->port = 80 ... $o->port_readable eq 'HTTP' ). Cf. code for earlier unpublished 'lookup' method type.

  • For StructBuiltin:

    Add -fatal flag to die if core func returns false / undef Add call method to recall method with alternative arguments. Add -nocall flag to not call core func on new.

  • Replace ClassName:static_hash_classname with Class:indexed_string.

Template Internals

  • Give users a way to do meta-method code-caching in Perl library hierarchy, rather than in /tmp/auto or other user-specified directory..

    Provide mechanism for pre-generating these at install time.

    Perhaps load these via do, rather than open/read/eval?

    Perhaps pre-generate expanded libs with all of the -imports resolved?

  • !

    Generate code files and load them instead.

    This would be similar to Class::Classgen, except that we'd do the generation at run-time the first time it was required, rather than in a separate pass.

    For example, given the following declaration:

      package Foo::Bar;
      Class::MakeMethods::Hash->import(-codecache=>'auto', scalar=>'foo');
      

    We should be able to write out the following file:

      cat 'auto/Foo/Bar/methods-line-2.pl'
      # NOTE: Generated for Foo::Bar by the Class::MakeMethods module.
      # Changes made here will be lost when Foo::Bar is modified.
      package Foo::Bar;
      sub foo {
        my $self = shift;
        if ( scalar @_ ) {
          $self->{'foo'} = shift();
        }
        $self->{'foo'}
      }

    Then on subsequent uses, we can just re-load the generated code:

      require "auto/Foo/Bar/methods-line-2.pl";

    To do this, we need to:

    -

    Provide an option to select this if desired; maybe ... import('-cache' => 'auto/', ...)?

    -

    Figure out which directory we can/should write into.

    -

    Re-evaluate the textual code templates, without generating the closures. Substitute in any _STATIC_ATTR_ values. Make other _ATTR_ values point to some public lookup table or package scalar.

    -

    Notice if the source file (or Class::MakeMethods modules) has been updated more recently than the generated file.

SEE ALSO

See Class::MakeMethods for an overview of the method-generation framework.

See Class::MakeMethods::Guide for a getting-started guide, annotated examples of usage, and a listing of the method generation classes included in this distribution.

See Class::MakeMethods::ReadMe for distribution, installation, version and support information.

5 POD Errors

The following errors were encountered while parsing the POD:

Around line 111:

Expected '=item *'

Around line 220:

Expected '=item *'

Around line 234:

Expected '=item *'

Around line 243:

Expected '=item *'

Around line 314:

Expected '=item *'