ISO vanilla class

Discussion in 'Perl Misc' started by Irving Kimura, Jan 27, 2004.

  1. It would be useful to have a generic, base class with a little bit
    more functionality than UNIVERSAL. The purpose of this class would
    be to eliminate tedious repetition when defining the constructor
    and accessor methods of a generic hash-ref object. It would let
    users specify what are the required and optional parameters for
    the constructor (along with the default values for the optional
    parameters), and would set up accessor methods (through AUTOLOAD)
    for these parameters, and maybe others. These methods could be
    overridden when the default behavior is inappropriate. So, defining
    a new class could be as simple as something like

    package Book;
    use base Vanilla;

    use constant required_params => 'title';
    use constant optional_params => { author => [ anonymous ],
    edition => 1,
    isbn => '',
    year => '',
    publisher => '' };
    use constant extra_accessors => 'id';


    and one could immediately begin using this object like this:

    use Book;

    my $book_1 = Book->new('JR', { author => ['Gaddis, William'] });
    my $book_2 = Book->new({ year => 2000 }); # triggers exception

    print $book_1->author; # prints 'Gaddis, William'
    print $book_1->edition(9); # prints '1' (previous value)
    $book_1->city('New York'); # triggers exception

    ....etc. I haven't thought through all the facilities this vanilla
    class would have, but something along these lines would be a nice
    start.

    Before I go off and reinvent the wheel, I thought that I'd ask if
    anything like this already exists.

    Thanks,

    Irv
    Irving Kimura, Jan 27, 2004
    #1
    1. Advertising

  2. Irving Kimura

    pkent Guest

    In article <bv635r$bpj$>,
    Irving Kimura <> wrote:

    [generic base class with more functions]

    Nice idea!


    > use Book;
    >
    > my $book_1 = Book->new('JR', { author => ['Gaddis, William'] });
    > my $book_2 = Book->new({ year => 2000 }); # triggers exception


    Personally I'd use a hash not a hash reference:

    Book->new('Book title', Author => 'Gaddis, William);

    And I'd not have that initial scalar, but simply:

    Book->new( Title => 'title', Author => 'Author' );

    Obviously the required parameters would be checked for, but I personally
    prefer things to have names so there's a bit less to remember.

    Personally I would, if you were going to do this, suggest some way of
    declaring the types of things, so that you could say that 'title' was
    both required and supposed to be a scalar. If someone put a hashref in
    there it'd throw an error. Of course such constraints would be optional


    > print $book_1->author; # prints 'Gaddis, William'
    > print $book_1->edition(9); # prints '1' (previous value)
    > $book_1->city('New York'); # triggers exception


    I think I prefer the explicit:

    $book->getAuthor;
    $book->setAuthor($value); # this would also have the type-checking
    mentioned above

    otherwise you will have a hard job setting a parameter to undef - how
    can a get-and-set routine know whether:

    $book->author;

    means to retrieve the author or to set the author to undef? I like
    explicit naming conventions. So you get more explicit method names
    (they're just as easy to make in AUTOLOAD), and by prefixing them you
    kind-of namespace the methods into get* and set* which will reduce the
    possibilities of name clashes.

    I'm sure there are other common things to put into this class too which
    would be handy. Just my 2p.

    P

    --
    pkent 77 at yahoo dot, er... what's the last bit, oh yes, com
    Remove the tea to reply
    pkent, Jan 27, 2004
    #2
    1. Advertising

  3. Also sprach pkent:

    > In article <bv635r$bpj$>,
    > Irving Kimura <> wrote:


    >> print $book_1->author; # prints 'Gaddis, William'
    >> print $book_1->edition(9); # prints '1' (previous value)
    >> $book_1->city('New York'); # triggers exception

    >
    > I think I prefer the explicit:
    >
    > $book->getAuthor;
    > $book->setAuthor($value); # this would also have the type-checking
    > mentioned above
    >
    > otherwise you will have a hard job setting a parameter to undef - how
    > can a get-and-set routine know whether:
    >
    > $book->author;
    >
    > means to retrieve the author or to set the author to undef? I like
    > explicit naming conventions.


    You can check the context. Void context would set the field, scalar or
    list context retrieves it (in case of a defined parameter).

    Tassilo
    --
    $_=q#",}])!JAPH!qq(tsuJ[{@"tnirp}3..0}_$;//::niam/s~=)]3[))_$-3(rellac(=_$({
    pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus})!JAPH!qq(rehtona{tsuJbus#;
    $_=reverse,s+(?<=sub).+q#q!'"qq.\t$&."'!#+sexisexiixesixeseg;y~\n~~dddd;eval
    Tassilo v. Parseval, Jan 27, 2004
    #3
  4. Irving Kimura

    Jay Tilton Guest

    Irving Kimura <> wrote:

    : It would be useful to have a generic, base class with a little bit
    : more functionality than UNIVERSAL. The purpose of this class would
    : be to eliminate tedious repetition when defining the constructor
    : and accessor methods of a generic hash-ref object.

    [snip]

    : Before I go off and reinvent the wheel, I thought that I'd ask if
    : anything like this already exists.

    See if something in CPAN's Class:: hierarchy excites you.
    Class::Accessor, Class::Struct, Class::MethodMaker,
    Class::MakeMethods, Class::Contract, . . . .
    Jay Tilton, Jan 27, 2004
    #4
  5. Irving Kimura

    J Krugman Guest

    In <> pkent <> writes:
    >I think I prefer the explicit:


    >$book->getAuthor;
    >$book->setAuthor($value); # this would also have the type-checking
    >mentioned above


    >otherwise you will have a hard job setting a parameter to undef - how
    >can a get-and-set routine know whether:


    >$book->author;


    >means to retrieve the author or to set the author to undef?


    What about $book->author(undef) for setting the field to undef?

    Irv
    J Krugman, Jan 28, 2004
    #5
  6. Irving Kimura

    bill Guest

    In <> (Jay Tilton) writes:

    >See if something in CPAN's Class:: hierarchy excites you.
    >Class::Accessor, Class::Struct, Class::MethodMaker,
    >Class::MakeMethods, Class::Contract, . . . .


    CPAN is great (and the CPAN module is God's gift to humanity), but
    CPAN has one huge flaw. I don't know how to fix this flaw, but it
    is very real: CPAN offers no way to distinguish the wheat from the
    chaff. If you search CPAN for the keyword 'Class' you'll get 400+
    hits. After 10-15 minutes of scanning this list, you may conclude
    that 15-20 modules are relevant to your interest (and miss 1 or 2
    you *should* be considering but aren't because their brief descriptions
    did not ring your bell.) How to narrow down the field? Reading
    the man pages for 20 modules, at 10 minutes per page, on average,
    will take almost 3 hours. Assuming you got that far, you may have
    narrowed the field down to 3-4 modules. To pick among these would
    require programming with them for a while; you need to determine
    the solidity of the code and the appositeness of the author's
    high-level design. We are talking at least 1-2 days of solid work
    here... I think this is probably an underestimate. This is
    beginning to approach the time it would take to roll one's own,
    which of course you'll do so brilliantly that you'll want to submit
    it to CPAN, only to make it less likely that anyone will use either
    yours or "competing" modules.

    bill
    bill, Jan 28, 2004
    #6
  7. Irving Kimura

    Chris Guest

    pkent wrote:
    > In article <bv635r$bpj$>,
    > Irving Kimura <> wrote:
    >
    > [generic base class with more functions]
    >
    > Nice idea!
    >
    >
    >
    >> use Book;
    >>
    >> my $book_1 = Book->new('JR', { author => ['Gaddis, William'] });
    >> my $book_2 = Book->new({ year => 2000 }); # triggers exception

    >
    >
    > Personally I'd use a hash not a hash reference:
    >
    > Book->new('Book title', Author => 'Gaddis, William);
    >
    > And I'd not have that initial scalar, but simply:
    >
    > Book->new( Title => 'title', Author => 'Author' );
    >
    > Obviously the required parameters would be checked for, but I personally
    > prefer things to have names so there's a bit less to remember.
    >
    > Personally I would, if you were going to do this, suggest some way of
    > declaring the types of things, so that you could say that 'title' was
    > both required and supposed to be a scalar. If someone put a hashref in
    > there it'd throw an error. Of course such constraints would be optional
    >
    >
    >
    >> print $book_1->author; # prints 'Gaddis, William'
    >> print $book_1->edition(9); # prints '1' (previous value)
    >> $book_1->city('New York'); # triggers exception

    >
    >
    > I think I prefer the explicit:
    >
    > $book->getAuthor;
    > $book->setAuthor($value); # this would also have the type-checking
    > mentioned above
    >
    > otherwise you will have a hard job setting a parameter to undef - how
    > can a get-and-set routine know whether:
    >
    > $book->author;
    >
    > means to retrieve the author or to set the author to undef? I like
    > explicit naming conventions.


    For accessors, I don't. The answer to your question "How?" is
    demonstrated in the simplest of Perl OO tutorials just about everywhere.
    When you write your accessor (a simple example that ignores the OP's
    request for AUTOLOAD):

    sub author {

    my $self = shift;
    $self->{author} = shift if (@_);
    $self->{author};

    }

    Now you can:

    $book->author( 'Larry Wall' );
    print $book->author() . "\n";
    (or even shorter is: print $book->author( 'Larry Wall' ) . "\n";
    Sets and then gets all in one.)

    Although I believe there are plenty of cases in the Class:: hierarchy to
    choose from. I wrote my own base class module that does most of what
    the OP wants, and it's VERY handy for creating objects on the fly with
    automatic accessors via AUTOLOAD. Also works just like another poster
    mentions -- just pass the hash:

    my $obj1 = My::Object->new( Name => 'Thurston Howell', EMail => 'none' );
    my $obj2 = My::Object->new( Hour => 12, Minute => 00, Second => 33 );

    print $obj1->Name() . " " . $obj1->EMail() . "\n";
    print $obj1->Name( 'Gilligan' ) . "\n";
    print $obj2->Hour() . ":" . $obj2->Minute() . ":" $obj2->Second( 45 ) .
    "\n";

    Almost senseless uses here (as with most short examples), but in
    programs, very powerful for creating base classes on the fly. Again,
    the Class:: hierarchy is probably way better than my base class, but it
    works for me.

    Chris
    -----
    Chris Olive
    chris +at+ technologEase +dot+ com
    http://www.technologEase.com
    (pronounced "technologies")
    Chris, Jan 28, 2004
    #7
  8. On Wed, 28 Jan 2004 03:06:55 +0000, bill wrote:

    > In <> (Jay Tilton)
    > writes:
    >
    >>See if something in CPAN's Class:: hierarchy excites you.
    >>Class::Accessor, Class::Struct, Class::MethodMaker, Class::MakeMethods,
    >>Class::Contract, . . . .

    >
    > CPAN is great (and the CPAN module is God's gift to humanity), but CPAN
    > has one huge flaw. I don't know how to fix this flaw, but it is very
    > real: CPAN offers no way to distinguish the wheat from the chaff. If
    > you search CPAN for the keyword 'Class' you'll get 400+ hits. After
    > 10-15 minutes of scanning this list, you may conclude that 15-20 modules
    > are relevant to your interest (and miss 1 or 2 you *should* be
    > considering but aren't because their brief descriptions did not ring
    > your bell.) How to narrow down the field? Reading the man pages for 20
    > modules, at 10 minutes per page, on average, will take almost 3 hours.
    > Assuming you got that far, you may have narrowed the field down to 3-4
    > modules. To pick among these would require programming with them for a
    > while; you need to determine the solidity of the code and the
    > appositeness of the author's high-level design. We are talking at least
    > 1-2 days of solid work here... I think this is probably an
    > underestimate. This is beginning to approach the time it would take to
    > roll one's own, which of course you'll do so brilliantly that you'll
    > want to submit it to CPAN, only to make it less likely that anyone will
    > use either yours or "competing" modules.


    I usually go to http://search.cpan.org/ *first* and do a search. Some of
    the things I look for are:

    - complete documentation; if the author can't take the time to explain the
    module's interface, then it's not worth my time to use it.

    - history/changes; modules that have been around awhile and have been
    updated over time are ones that will be around years from now.

    - ease of use; if it takes an enormous effort on my part to get what I
    want, then I might as well do it all myself. Modules are suppose to make
    life easy, not complicated - I can do that on my own, thank you very much
    ;-)

    - portable; what's the point of using some modules if the code isn't
    portable. That's not to say *all* modules need to be portable. But given
    the choice between one that is and one that isn't, I'll go for the
    portable one every time.

    - task-specific; no need to use a hammer when a fly swatter is in order
    ;-) If the module is so bloated with "stuff", then, again, I might as
    well do it myself. Some modules allow you to import only those methods
    you *need*, not the whole stinking thing into the namespace. Given a
    choice between a module that allows *me* to decide what methods I want to
    use versus one that doesn't, I'll use the one that does.

    - word of mouth; nothing beats asking what others have used. Make sure
    you get a well rounded view of the module and it's capabilities. Make
    sure you get bad reviews - the evil known is better than the evil that's
    unknown :)

    Good modules to show what I'm talking about are:
    CGI, DBI, LWP, Template Toolkit, Net::SMTP, and Net::FTP.

    That's just a few tips for you when searching for "that special module" I
    use. I hope you find these tips useful. It might cut your search time
    down to about a day - depending on what you want to do ;-)

    HTH

    --
    Jim

    Copyright notice: all code written by the author in this post is
    released under the GPL. http://www.gnu.org/licenses/gpl.txt
    for more information.

    a fortune quote ...
    Law of the Perversity of Nature: You cannot successfully
    <determine beforehand which side of the bread to butter.
    James Willmore, Jan 28, 2004
    #8
  9. Irving Kimura

    bill Guest

    Thanks for your tips. I particularly like this one:

    In <> James Willmore <> writes:

    >- word of mouth; nothing beats asking what others have used.


    I totally agree. This is also the hardest tip to put to practice,
    because when you ask around, like the OP did, almost invariably
    the replies you'll get will be along the lines of "check out CPAN;
    tons of stuff there", and you'll be back to square 1.

    bill
    bill, Jan 28, 2004
    #9
  10. Irving Kimura

    Anno Siegel Guest

    Tassilo v. Parseval <-aachen.de> wrote in comp.lang.perl.misc:
    > Also sprach pkent:
    >
    > > In article <bv635r$bpj$>,
    > > Irving Kimura <> wrote:

    >
    > >> print $book_1->author; # prints 'Gaddis, William'
    > >> print $book_1->edition(9); # prints '1' (previous value)
    > >> $book_1->city('New York'); # triggers exception

    > >
    > > I think I prefer the explicit:
    > >
    > > $book->getAuthor;
    > > $book->setAuthor($value); # this would also have the type-checking
    > > mentioned above
    > >
    > > otherwise you will have a hard job setting a parameter to undef - how
    > > can a get-and-set routine know whether:
    > >
    > > $book->author;
    > >
    > > means to retrieve the author or to set the author to undef? I like
    > > explicit naming conventions.

    >
    > You can check the context. Void context would set the field, scalar or
    > list context retrieves it (in case of a defined parameter).


    I strongly disagree. Context should control what a sub returns, not what
    it does. I consider other behavior unusual and cruel :)

    In the case of accessors, divine intention wants the number of arguments
    to control the behavior: "$book->author" retrieves the author, "book->
    author( 'Mann')" sets it to "Mann", which it also returns, and "$book->
    author( undef)" sets it to undef and returns undef. What could be more
    logical (and straight-forward to code).

    However, this disagreement, as well as others in this thread (which I
    haven't even entirely read at this point) show why a module like the OP
    describes doesn't exist, or, if it does, why it hasn't conquered the Perl
    world. There are so many details in the interface to disagree about that,
    with any particular implementation, there will be one detail for every
    potential user to disagree with. Since the module doesn't do anything hard,
    you'll end up writing your own.

    Anno
    Anno Siegel, Jan 28, 2004
    #10
  11. Irving Kimura

    Anno Siegel Guest

    bill <> wrote in comp.lang.perl.misc:
    >
    >
    > Thanks for your tips. I particularly like this one:
    >
    > In <> James Willmore
    > <> writes:
    >
    > >- word of mouth; nothing beats asking what others have used.

    >
    > I totally agree. This is also the hardest tip to put to practice,
    > because when you ask around, like the OP did, almost invariably
    > the replies you'll get will be along the lines of "check out CPAN;
    > tons of stuff there", and you'll be back to square 1.


    After looking at the documentation, I tend to look at the code rather early
    ("look" with CPAN, "z" with CPANPLUS). Bad code is pretty obvious, and
    a distressing number of modules can be eliminated that way.

    It also helps to look at authors' PAUSE directories. What else have they
    written? Anything popular there? How do they maintain other modules?
    (If a module hasn't been updated for a while, it may simply mean it's
    stable.)

    Otherwise, yes, finding a module on CPAN can be time-consuming. The
    "insert-problem-description-here" machine is almost working now...

    Anno
    Anno Siegel, Jan 28, 2004
    #11
  12. Also sprach Anno Siegel:

    > Tassilo v. Parseval <-aachen.de> wrote in comp.lang.perl.misc:
    >> Also sprach pkent:
    >>
    >> > In article <bv635r$bpj$>,
    >> > Irving Kimura <> wrote:

    >>
    >> >> print $book_1->author; # prints 'Gaddis, William'
    >> >> print $book_1->edition(9); # prints '1' (previous value)
    >> >> $book_1->city('New York'); # triggers exception
    >> >
    >> > I think I prefer the explicit:
    >> >
    >> > $book->getAuthor;
    >> > $book->setAuthor($value); # this would also have the type-checking
    >> > mentioned above
    >> >
    >> > otherwise you will have a hard job setting a parameter to undef - how
    >> > can a get-and-set routine know whether:
    >> >
    >> > $book->author;
    >> >
    >> > means to retrieve the author or to set the author to undef? I like
    >> > explicit naming conventions.

    >>
    >> You can check the context. Void context would set the field, scalar or
    >> list context retrieves it (in case of a defined parameter).

    >
    > I strongly disagree. Context should control what a sub returns, not what
    > it does. I consider other behavior unusual and cruel :)


    Just a matter of documenting it properly. :)

    As a matter of fact I quickly realized that context is indeed not
    necessary because you can always check whether @_ contains something
    (even undef) or not. Had I thought about this (rather obvious) fact when
    reading the OP, I wouldn't have made this questionable suggestion.

    > However, this disagreement, as well as others in this thread (which I
    > haven't even entirely read at this point) show why a module like the OP
    > describes doesn't exist, or, if it does, why it hasn't conquered the Perl
    > world. There are so many details in the interface to disagree about that,
    > with any particular implementation, there will be one detail for every
    > potential user to disagree with. Since the module doesn't do anything hard,
    > you'll end up writing your own.


    If you ask me, I find most of the modules in the Class:: namespace
    rather useless for the reasons you mentioned. Often I find they'd
    require more reading of the docs than they could save later when writing
    the code. In many cases they restrict Perl's flexibility and in doing so
    they restrict me as well.

    Tassilo
    --
    $_=q#",}])!JAPH!qq(tsuJ[{@"tnirp}3..0}_$;//::niam/s~=)]3[))_$-3(rellac(=_$({
    pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus})!JAPH!qq(rehtona{tsuJbus#;
    $_=reverse,s+(?<=sub).+q#q!'"qq.\t$&."'!#+sexisexiixesixeseg;y~\n~~dddd;eval
    Tassilo v. Parseval, Jan 28, 2004
    #12
  13. In article <bv80om$3dg$>, bill <>
    wrote:

    > Thanks for your tips. I particularly like this one:
    >
    > In <> James Willmore
    > <> writes:
    >
    > >- word of mouth; nothing beats asking what others have used.

    >
    > I totally agree. This is also the hardest tip to put to practice,
    > because when you ask around, like the OP did, almost invariably
    > the replies you'll get will be along the lines of "check out CPAN;
    > tons of stuff there", and you'll be back to square 1.


    Thats presumably because the usual assumption (and most likely, usually
    correst assumption) is that the original poster _hasn't_ searched CPAN
    yet.

    A query along the lines of:

    "I need a module to do foo. I found Class::Foo, Class::Foo::Simple,
    Data::Bah, and Universal::FooBah on Cpan. Has anyone used any of these
    (or any other alternatives)? Any hints as to which one works best?"

    Would generate a significantly different type of response...

    big

    --
    'When I first met Katho, she had a meat cleaver in one hand and
    half a sheep in the other. "Come in", she says, "Hammo's not here.
    I hope you like meat.' Sharkey in aus.moto
    Iain Chalmers, Jan 28, 2004
    #13
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. VisionSet

    Custom or vanilla Collection/Map?

    VisionSet, Sep 15, 2003, in forum: Java
    Replies:
    3
    Views:
    368
    Harald Hein
    Sep 15, 2003
  2. VisionSet
    Replies:
    1
    Views:
    314
    Roedy Green
    Jul 3, 2004
  3. Art
    Replies:
    3
    Views:
    444
  4. Neil Benn

    Vanilla python path

    Neil Benn, Jul 25, 2005, in forum: Python
    Replies:
    0
    Views:
    340
    Neil Benn
    Jul 25, 2005
  5. markritter150

    Vanilla Ice is back!

    markritter150, Jun 3, 2008, in forum: C Programming
    Replies:
    6
    Views:
    295
Loading...

Share This Page