OO Perl Online Learning

Discussion in 'Perl Misc' started by Xiong Changnian, Feb 5, 2007.

  1. I've browsed my fingers off, read all the obvious sources and quite a
    few that are off-topic for my needs. I've even been to the local
    computer bookstore; there are many books on OO Perl, each with a hefty
    price tag. I'm not cheap; I'm broke.

    There seems to be little online between perltoot and the like; and
    highly specific discussions that assume advanced knowledge and dive into
    esoterics. I don't see the bridge -- general intermediate discussion of
    OO Perl.

    Here are the kinds of questions I've been trying to answer for myself:

    * What is all this about makefiles and installation? Why isn't it enough
    to download a module and un-tar it to my lib directory? Perhaps I'm
    handicapped, running MacPerl under OS 9. I haven't been able to install
    anything I've downloaded, not even stuff that shouldn't have anything to
    do with the Mac file system.

    * All the CPAN modules seem to be just one class per module; every
    source I've read says you *can* declare more than one package in a file
    but it seems that in practice, it's one class, one package, one module,
    one file. Yet I'm contemplating a set of perhaps 20 closely related
    classes. I don't know if I'm taking the wrong approach or if there's a
    way to bundle them neatly. And yes, I've read a little on CPAN bundles;
    I'm still in the dark. I suspect this question ties into the last.

    * The *use* pragma makes a class available in a given file but doesn't
    seem to propagate; I have to *use* the class everywhere I, well, use it.
    Is there no single place I can declare an entire set of classes for use
    in any script that *uses* that file? This obviously ties into the last.

    * Same question, different angle: If I *use* and inherit among a group
    of classes, it seems I run into dependency problems. Is this a lack of
    clear thinking on my part and I need to draw up a strict table of
    dependencies and work out the order in which the compiler sees
    declarations? Or can I just throw everything in if I declare them the
    "right" way?

    * What's all this about test suites? I can understand writing a script
    that stands on its own and exercises a module. I see discussions that
    look as though these test scripts are being generated automatically in
    some way.

    * Should I *always* use strict and use warn? I've been doing just that,
    beating the code until it works under these conditions. I see a lot of
    code online that shouldn't, though. Right now, I'm using symbolic refs
    in one place and I feel I oughtn't.

    Nobody has to take the time to answer any of these questions *here* but
    I'd love a pointer or five.

    Xiong
    --
    Xiong Changnian
    xiong102ATxuefangDOTcom

    --
    Posted via a free Usenet account from http://www.teranews.com
     
    Xiong Changnian, Feb 5, 2007
    #1
    1. Advertising

  2. Xiong Changnian

    Scott Bryce Guest

    Xiong Changnian wrote:

    > I've browsed my fingers off, read all the obvious sources and quite a
    > few that are off-topic for my needs. I've even been to the local
    > computer bookstore; there are many books on OO Perl, each with a hefty
    > price tag. I'm not cheap; I'm broke.


    The public library is your friend. My local library has a copy of
    Damian Conway's Object Oriented Perl.
     
    Scott Bryce, Feb 5, 2007
    #2
    1. Advertising

  3. >>>>> "XC" == Xiong Changnian <> writes:

    XC> * What is all this about makefiles and installation? Why isn't
    XC> it enough to download a module and un-tar it to my lib
    XC> directory? Perhaps I'm handicapped, running MacPerl under OS
    XC> 9. I haven't been able to install anything I've downloaded,
    XC> not even stuff that shouldn't have anything to do with the Mac
    XC> file system.

    First off, you are indeed handicapped by running MacPerl under OS 9.

    It isn't enough to simply download a module and un-tar it because a
    number of other files may need to be changed. The module installation
    process also includes ensuring the module is as packaged, that all
    prerequisites are in place, and that all necessary files (such as
    those used to generate perldoc perllocal) are updated. Some modules
    also have stubs to link to C libraries, which require a C compiler.
    Because Perl was conceived on Unix, the most obvious way to manage all
    this was with Makefiles.

    On platforms that don't include compilers and Makefiles, alternative
    approaches have been developed, from BSD ports and packages to
    ActiveState Perl package repositories. Unfortunately for you, OS 9 is
    neither Unixlike nor actively supported, which means you're out of luck.

    If you insist on not upgrading to OS X, you might consider getting an
    external drive and installing one of the PPC Linuxes on it. If you
    insist on remaining on OS 9, you need to prepare yourself for a lot of
    frustration and annoyance.

    XC> * What's all this about test suites? I can understand writing
    XC> a script that stands on its own and exercises a module. I see
    XC> discussions that look as though these test scripts are being
    XC> generated automatically in some way.

    They aren't necessarily generated automatically, but if you conform
    with the behavior expected by Test::Simple and its relatives, you can
    run them automatically during development and run them automatically
    at installation time.

    XC> * Should I *always* use strict and use warn? I've been doing
    XC> just that, beating the code until it works under these
    XC> conditions. I see a lot of code online that shouldn't,
    XC> though. Right now, I'm using symbolic refs in one place and I
    XC> feel I oughtn't.

    Yes, you should *always* use strictures and warnings, especially as
    they're both scoped, and when you need to do something that violates a
    stricture or warning, you can turn that diagnostic off in the smallest
    possible scope. Even then, there's almost always a better way.

    XC> Nobody has to take the time to answer any of these questions
    XC> *here* but I'd love a pointer or five.

    As to your questions about OO syntax and inheritance --
    _Object-Oriented Perl_, by Damian Conway. Good luck.

    Charlton


    --
    Charlton Wilbur
     
    Charlton Wilbur, Feb 5, 2007
    #3
  4. Xiong Changnian

    John Bokma Guest

    Xiong Changnian <> wrote:

    > * All the CPAN modules seem to be just one class per module;


    I can confirm that this is /not/ true. Just grep for package over all pm
    files and I am sure you will find modules already installed that have more
    then one class per pm file.

    > one file. Yet I'm contemplating a set of perhaps 20 closely related
    > classes.


    Unless they are very short (linewise) you might be better of to put each
    in a file of their own. Or a combination. 20 classes in one file is IMO a
    pain in the ass to edit, even if you can split your window in 2 or more
    views.

    > * Should I *always* use strict and use warn? I've been doing just that,
    > beating the code until it works under these conditions. I see a lot of
    > code online that shouldn't, though. Right now, I'm using symbolic refs
    > in one place and I feel I oughtn't.


    Show the code. The nice thing of use warnings is that you can disable
    warnings for a block.

    --
    John Experienced Perl programmer: http://castleamber.com/

    Perl help, tutorials, and examples: http://johnbokma.com/perl/
     
    John Bokma, Feb 5, 2007
    #4
  5. Xiong Changnian

    Guest

    Xiong Changnian <> wrote:
    > I've browsed my fingers off, read all the obvious sources and quite a
    > few that are off-topic for my needs. I've even been to the local
    > computer bookstore; there are many books on OO Perl, each with a hefty
    > price tag. I'm not cheap; I'm broke.
    >
    > There seems to be little online between perltoot and the like;


    By "the like", do you mean perlobj, perlboot, perltooc, perlmod and
    perlbot?

    > and
    > highly specific discussions that assume advanced knowledge and dive into
    > esoterics. I don't see the bridge -- general intermediate discussion of
    > OO Perl.
    >
    > Here are the kinds of questions I've been trying to answer for myself:
    >
    > * What is all this about makefiles and installation? Why isn't it enough
    > to download a module and un-tar it to my lib directory?


    Usually it is. If it isn't, it could be that the module is not pure Perl
    but has XS code that needs to be compiled, or it is dependent on other
    modules which you don't have installed.


    > * All the CPAN modules seem to be just one class per module;


    Look at more modules. Tie::File, for example, has two helper classes.
    And that is not unusual. Running:

    egrep -rc '^package' $PERL5LIB | awk -F: '$2>1 {print $1}'

    Should point out some more candidates for having more than one class per
    file.

    > every
    > source I've read says you *can* declare more than one package in a file
    > but it seems that in practice, it's one class, one package, one module,
    > one file. Yet I'm contemplating a set of perhaps 20 closely related
    > classes. I don't know if I'm taking the wrong approach or if there's a
    > way to bundle them neatly.


    You just put all the code in one file with multiple package statements.
    Unless you need to import stuff, there should be no problem.


    > * The *use* pragma makes a class available in a given file but doesn't
    > seem to propagate;


    Could you give an example? I've not had this problem with OO modules.

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
     
    , Feb 5, 2007
    #5
  6. On 2007-02-05 17:15, Xiong Changnian <> wrote:
    > * What is all this about makefiles and installation? Why isn't it enough
    > to download a module and un-tar it to my lib directory?


    If it's a pure perl module, that will work. However, as Charlton already
    mentioned, some modules are not pure perl, and the installation process
    also checks dependencies and does some bookkeeping.

    There is another important point: Testing.

    By downloading the module into one directory and then installing it you
    can test a module before you install it (and possibly overwrite a
    working version with a non-working version). Most Modules on CPAN come
    with a test-suite. If you run "make test" before "make install" (cpan
    will do that automatically), you can be reasonably sure that the module
    will work as expected on your system (which is even more important if
    you run a relatively exotic system like MacOS 9 - you do need a "make"
    command, though. Only a few distributions use Module::Build instead of
    Makemaker).



    > * All the CPAN modules seem to be just one class per module;


    Nope. There are quite a few which have more than one class/package per
    file.

    > every source I've read says you *can* declare more than one package in
    > a file but it seems that in practice, it's one class, one package, one
    > module, one file.


    Putting several packages into a single file is generally less clear, and
    you can't "use" a package if the filename can't be derived from the
    package name - so all your "public" packages must be in a file of their
    own. "Private" packages which aren't supposed to be "use"d by the
    programmer are sometimes put into the same file as the package which
    uses them.

    > Yet I'm contemplating a set of perhaps 20 closely related classes. I
    > don't know if I'm taking the wrong approach or if there's a way to
    > bundle them neatly. And yes, I've read a little on CPAN bundles;


    No need to bundle them. If they are closely related, put them into the
    same distribution.


    > * The *use* pragma makes a class available in a given file but doesn't
    > seem to propagate; I have to *use* the class everywhere I, well, use it.


    Not quite. You only need to "use" the class where you need to import
    its symbols, and obviously you need to load the module to use any code
    in it, so you need to "use" (or require, do, whatever) it somewhere.

    But you can use objects of classes and even class methods of packages
    which you didn't use directly. For example, in

    use MIME::parser;

    my $parser = new MIME::parser();
    my $entity = $parser->parse(\*STDIN);
    my $head = $entity->head();

    $entity is an object of the class MIME::Entity, and $head is a
    MIME::Head. You don't need to "use" these modules to use these objects.
    MIME::parser "use"s them, and that's sufficient.


    > * Same question, different angle: If I *use* and inherit among a group
    > of classes, it seems I run into dependency problems. Is this a lack of
    > clear thinking on my part and I need to draw up a strict table of
    > dependencies and work out the order in which the compiler sees
    > declarations? Or can I just throw everything in if I declare them the
    > "right" way?


    Inheritance is a bit of a sore spot in perl. It depends on how the
    classes you want to inherit from are written.


    > * What's all this about test suites?


    They help you find bugs.

    > I can understand writing a script that stands on its own and exercises
    > a module.


    A test suite is a collection of such scripts.

    > I see discussions that look as though these test scripts are being
    > generated automatically in some way.


    No, they aren't (normally) *generated* automatically. You need to write
    them yourself, and that often takes as much thought as writing the
    actual code (unless your specification is already very detailed and
    formal, in that (rare) case, a test-suite can be genereted from the spec
    (semi-)automatically). However, the test suite is *run* every time you
    type "make test" and every time someone installs the distribution via
    CPAN. So errors which are covered by a test-case will be found soon.

    hp


    --
    _ | Peter J. Holzer | Es ist ganz einfach ihn zu verstehen, wenn
    |_|_) | Sysadmin WSR | man nur alle wichtigen Worte im Satz durch
    | | | | andere ersetzt.
    __/ | http://www.hjp.at/ | -- Nils Ketelsen in danr
     
    Peter J. Holzer, Feb 5, 2007
    #6
  7. In article <>,
    Charlton Wilbur <> wrote:

    > If you insist on not upgrading to OS X, you might consider getting an
    > external drive and installing one of the PPC Linuxes on it. If you
    > insist on remaining on OS 9, you need to prepare yourself for a lot of
    > frustration and annoyance.


    It's difficult to explain why I still run OS 9 and I'm not sure this is
    the place for it. Assume all the reasons given by bad managers for
    legacy systems and stir in a large helping of poverty. Fact is, I've got
    my beige G3 hot-rodded, hardware and software, to an impressive extent.
    It works -- most of the time -- very well.

    I tried, over a period of about six months, to install various flavors
    of Linux on a beige Mac. It was a nightmare. I think the way out of my
    corner is to wait until I have enough workspace to set up two
    workstations, buy a cheap Intel box and put a standard Linux distro on
    it -- never touch windoz -- and go back and forth between the two
    systems until I make the transition. Even then, I anticipate a PowerBook
    for years to come. There is simply no reasonable way, in some cases, to
    convert old work files.

    > if you conform
    > with the behavior expected by Test::Simple...


    I have plain Test installed and I looked over the POD before I posted
    here. It assumes I already know what the author is driving at. I'll
    exercise it a bit and see what happens. I'm afraid I'm not really an
    experimentalist at heart; I like to read the manual. I've been looking
    at a number of files shipped with MacPerl with the extension .t as well.
    I suspect I will learn something.


    In article <>,
    Scott Bryce <> wrote:

    > The public library is your friend. My local library has a copy of
    > Damian Conway's Object Oriented Perl.


    I should have thought of that. This *is* San Jose. Even $21.50 for the
    PDF is too rich for my blood.


    In article <Xns98CE822A7254castleamber@130.133.1.4>,
    John Bokma <> wrote:

    > Just grep for package over all pm
    > files and I am sure you will find modules already installed that have more
    > then one class per pm file.


    I've been looking for such examples; I'll look harder.

    > Unless they are very short (linewise) you might be better of to put each
    > in a file of their own. Or a combination. 20 classes in one file is IMO a
    > pain in the ass to edit, even if you can split your window in 2 or more
    > views.


    You're right, of course. But 20 files is also a kind of pain. I think a
    balanced hierarchy would be something like 5 distinct files, one each
    for important, complex classes; plus another 2 or 3 files containing
    these itty-bitty classes that have only perhaps 2 methods each.

    > Show the code. The nice thing of use warnings is that you can disable
    > warnings for a block.


    I posted that before. Here again:

    sub report_sets {
    my @keys = sort keys %{ $ref->{SETS} };
    foreach (@keys) {
    &{"report_" . lc($_)} ($ref->{SETS}{$_})
    or die ("No report subroutine for $_.");
    };
    };

    Many such subs, one for each hash key; some actually do something.
    Symbolic ref, so I bracket this with no strict "refs";

    It *does* work but I'm pretty sure there *is* a better way; I just have
    to make every hash level an object -- which leads to a proliferation of
    "internal" classes, most obviously named after the hash keys which
    invoke them. Thus my worries about -- "bundle bloat"?


    In article <20070205150844.839$>,
    wrote:

    > By "the like", do you mean perlobj, perlboot, perltooc, perlmod and
    > perlbot?


    Yes, Sir, I believe I've read them all three to seven times. They're
    pretty basic. There may still be stuff to be gleaned from them but I
    look forward to paging through Conway.

    > > * All the CPAN modules seem to be just one class per module;

    >
    > Look at more modules. Tie::File, for example, has two helper classes.
    > And that is not unusual.


    I don't have Tie::File handy but I'm just now looking over Tie::Array,
    which has in the file both package Tie::Array and package Tie::StdArray;
    and I will study this until I see how it works. Good tip.

    > > * The *use* pragma makes a class available in a given file but doesn't
    > > seem to propagate;

    >
    > Could you give an example?


    I'd better put a lengthy code example in another post. First, I want to
    strip out all possible dead wood. Thanks for the invitation.

    And many thanks to all for the extensive help.

    Xiong
    --
    Xiong Changnian
    xiong102ATxuefangDOTcom

    --
    Posted via a free Usenet account from http://www.teranews.com
     
    Xiong Changnian, Feb 5, 2007
    #7
  8. >>>>> "XC" == Xiong Changnian <> writes:

    XC> In article <>,
    XC> Charlton Wilbur <> wrote:

    >> If you insist on not upgrading to OS X, you might consider
    >> getting an external drive and installing one of the PPC Linuxes
    >> on it. If you insist on remaining on OS 9, you need to prepare
    >> yourself for a lot of frustration and annoyance.


    XC> It's difficult to explain why I still run OS 9 and I'm not
    XC> sure this is the place for it.

    It doesn't matter, and it isn't. What I said, I stand by; the fact
    that you have very good reasons to remain on OS 9 will not alter the
    frustration and annoyance.

    Charlton



    --
    Charlton Wilbur
     
    Charlton Wilbur, Feb 5, 2007
    #8
  9. Xiong Changnian

    Uri Guttman Guest

    >>>>> "XC" == Xiong Changnian <> writes:


    XC> In article <>,
    XC> Scott Bryce <> wrote:

    >> The public library is your friend. My local library has a copy of
    >> Damian Conway's Object Oriented Perl.


    XC> I should have thought of that. This *is* San Jose. Even $21.50 for the
    XC> PDF is too rich for my blood.

    it is old enough that there are many used copies out there. check amazon
    and ebay for copies.

    also beginning perl is online and free at learn.perl.org. i don't how
    deep it gets into OO but it may help some

    XC> In article <Xns98CE822A7254castleamber@130.133.1.4>,
    XC> John Bokma <> wrote:

    >> Just grep for package over all pm
    >> files and I am sure you will find modules already installed that have more
    >> then one class per pm file.


    XC> I've been looking for such examples; I'll look harder.

    >> Unless they are very short (linewise) you might be better of to put each
    >> in a file of their own. Or a combination. 20 classes in one file is IMO a
    >> pain in the ass to edit, even if you can split your window in 2 or more
    >> views.


    XC> You're right, of course. But 20 files is also a kind of pain. I think a
    XC> balanced hierarchy would be something like 5 distinct files, one each
    XC> for important, complex classes; plus another 2 or 3 files containing
    XC> these itty-bitty classes that have only perhaps 2 methods each.

    i think 20 related classes means you are over classifying things. that
    is the java and not the perl way. do they really need to be separate
    classes? are they all variants of each other or a parent class? are you
    reusing them in different places or only all at once? whenever i see too
    many of anything in one place i suspect a design flaw.

    XC> I posted that before. Here again:

    XC> sub report_sets {
    XC> my @keys = sort keys %{ $ref->{SETS} };
    XC> foreach (@keys) {

    use named variable when possible. it makes for more easily understood
    code.

    XC> &{"report_" . lc($_)} ($ref->{SETS}{$_})

    eww, that is symrefs. make a dispatch table and your code will be
    cleaner and safer. google this group for 'dispatch table' and you will
    find many threads on it.


    XC> or die ("No report subroutine for $_.");
    you can't die that late. you already called the unknown sub. a dispatch
    table will allow a check before calling which is what you want.

    XC> };
    XC> };

    XC> Many such subs, one for each hash key; some actually do something.
    XC> Symbolic ref, so I bracket this with no strict "refs";

    bad boy! no cookie for you. dispatch tables are the best way to do that
    and no symrefs are needed.

    XC> It *does* work but I'm pretty sure there *is* a better way; I just have
    XC> to make every hash level an object -- which leads to a proliferation of
    XC> "internal" classes, most obviously named after the hash keys which
    XC> invoke them. Thus my worries about -- "bundle bloat"?

    you don't have to make every hash level an object. that is again the
    java way and i doubt you need to do that here. too many objects is just
    as bad as too few. objects are meant to help organized code and data,
    not tag them to death like xml.

    XC> Yes, Sir, I believe I've read them all three to seven times. They're
    XC> pretty basic. There may still be stuff to be gleaned from them but I
    XC> look forward to paging through Conway.

    you need an eighth reading! :) OOP is a great book and you should beg
    borrow or (well not really) steal a copy. used copies are your best bet
    as i have said.

    >> > * The *use* pragma makes a class available in a given file but doesn't
    >> > seem to propagate;

    >>
    >> Could you give an example?


    XC> I'd better put a lengthy code example in another post. First, I want to
    XC> strip out all possible dead wood. Thanks for the invitation.

    use does two things and you seem to be confusing them. one is to load a
    module and that needs to be done only once (basically the same as
    require but which loads at runtime). the other is to call the import
    mathod of the class you loaded and that needs to be done in each file
    that wants exported symbols. but if you are doing only OO in a module
    and not exporting anything then it can be loaded once with use. again, i
    suspect you are creating too many classes and may be crossing OO with
    exported symbols which is not a good idea.

    when you post more code it will be easier to help with the bigger design
    issues i sense here. i smell an XY problem which means you picked a
    solution X and are working hard but you really need solution Y.

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
     
    Uri Guttman, Feb 5, 2007
    #9
  10. Multiple Classes per File and use (was: OO Perl...)

    Okay, thanks for help given -- the most helpful thing was the naked
    assertion that multiple classes *may* be coded into a single file. I now
    have my test case working.

    My problem seems not to have anything to do with Mac filesystem but it
    may. The issue is that I lost heart when I could not seem to get methods
    recognized even though I had these nice use and base declarations in
    each file.

    For the following, I've translated folders into *nix directory
    conventions.

    The .pl testbed itself is in /usr/; there is a subdir /usr/Jam/ which
    contains, in Band.pm, the putative "important" class and, in Guts.pm,
    three "helper" or "internal" classes.

    It seems that I must use Jam::Band; I can't use Band. On the other hand,
    I must use base qw(Band) and not use base qw(Jam::Band). You'll forgive
    me if I find this inconsistent. I'm sure there's a good reason; I just
    don't see it.

    I've always put the package declaration first, ahead of use statements;
    it seems logical that if I'm declaring multiple packages, I may as well
    put the use statements before the first package. I feel it might be best
    to keep the package first, though, in single-class files.

    I'm still not sure if I *must* use base for each class, so long as they
    all inherit from the same branch. This should, I suspect, always be the
    case; let there be another file for classes that inherit from another
    branch but group the tiny helper classes that are all "siblings" in one
    file. This is something I can thrash out by experiment.

    Again, thanks for the prods. I beat on this for hours with no success
    but it all started to work when I began to believe it could be done.

    Xiong


    ### /usr/jamsession.pl ###

    use strict;
    use warnings;
    use Jam::Band;
    ....
    my $one = new Band;
    $one->add('Tuba','whonk');
    $one->play('Tuba');
    ....

    ### /usr/Jam/Band.pm ###

    package Band;
    use strict;
    use warnings;
    use Jam::Guts;

    sub new {
    ....
    };

    sub add {
    ...
    my $instrument = new $kind;
    $instrument->tune($sound);
    $obj->{$kind} = $instrument;
    };
    ....
    ....

    ### /usr/Jam/Guts.pm ###

    use strict;
    use warnings;
    use Jam::Band;

    package Tuba;
    use base qw(Band);

    sub tune {
    ....
    };

    package Drum;
    use base qw(Band);

    sub tune {
    ....
    };
    ....
    ....

    ######
    --
    Xiong Changnian
    xiong102ATxuefangDOTcom

    --
    Posted via a free Usenet account from http://www.teranews.com
     
    Xiong Changnian, Feb 5, 2007
    #10
  11. Xiong Changnian

    Guest

    Re: Multiple Classes per File and use (was: OO Perl...)

    Xiong Changnian <> wrote:
    >
    > The .pl testbed itself is in /usr/; there is a subdir /usr/Jam/ which
    > contains, in Band.pm, the putative "important" class and, in Guts.pm,
    > three "helper" or "internal" classes.
    >
    > It seems that I must use Jam::Band; I can't use Band.


    You could use Band as long as /usr/Jam was in the perl lib path, or if you
    run the script with a cwd of /usr/Jam. If neither of these is the case,
    then you need the Jam:: or else perl doesn't know to look for Band in the
    Jam directory. Presumably you only want /usr in your perl lib path, and
    you want this to refered to as Jam::Band, right?

    > On the other hand,
    > I must use base qw(Band) and not use base qw(Jam::Band). You'll forgive
    > me if I find this inconsistent. I'm sure there's a good reason; I just
    > don't see it.


    See the next item below.

    ....
    >
    > ### /usr/Jam/Band.pm ###
    >
    > package Band;


    If you want to refer to this as Jam::Band in other classes "use base"
    lines, then the "package" statement would need to declare it as such:

    package Jam::Band;


    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
     
    , Feb 6, 2007
    #11
  12. Re: Multiple Classes per File and use (was: OO Perl...)

    Uh, thanks to Xho for explaining why I use Jam::Band but use base Band
    when I package Band. Sorry if I'm stubborn and cranky but well, I still
    find it inconsistent.

    But if I can use Jam::Band and use base Jam::Band if I package
    Jam::Band, then I will sleep better. Thanks.


    In article <>,
    Uri Guttman <> wrote:

    > i think 20 related classes means you are over classifying things. that
    > is the java and not the perl way. do they really need to be separate
    > classes? are they all variants of each other or a parent class? are you
    > reusing them in different places or only all at once? whenever i see too
    > many of anything in one place i suspect a design flaw.


    Ah, I covered my application in too much detail in an earlier thread;
    I'd better not repeat myself. Yes; yes they are all related but although
    they can reasonably inherit a few methods, some will be distinctly
    different; they will be used in a wide variety of configurations; and I
    agree.

    The nub of it is that some objects (classes, but bear with me) logically
    include others, just as Dinner includes Entree and Desert. This makes
    sense to the user of the -- Restaurant *thing* (Not a module, not a
    bundle, the whole folder full of related stuff = project?). Meanwhile,
    it seems that most of these objects have similar structures. For
    instance, every one of my logical objects has a first-level SELF key,
    pointing to a small hash with keys like NAME and COLOR. Other
    first-level keys may point to sets of objects or arrays of data.

    The point being that since each of these objects has a SELF key/hash
    containing similar data, it makes sense to me to build a Self object and
    write general methods to handle it. Self has no "external" meaning to
    the outermost, using script; perhaps I should call it _Self. There are
    already a couple cases like this and by the time the entire *thing* is
    written, I expect about 10 logical objects and perhaps another 10
    internal helper objects. What I'm doing, without going into too much
    detail, really does involve a lot of distinct classes of things --
    things that behave in fundamentally different ways, not just dozens of
    instances of the same class.

    I agree that my current method, in which I tried to limit myself to
    logically sensible objects and went bashing around with symbolic refs,
    is ugly and Bad. That's why I posted here: I was happy I got it to work
    and immediately looked for a better solution.

    Now, I've got that silly example working and I'm (momentarily) content.
    One top class in its own file with new() and other general cross-project
    methods; one file each for the big, external classes; one helper file
    for all the small _internal classes; and all inherit from the top.

    I really can't thank you guys enough.

    > use named variable when possible.
    > it makes for more easily understood code.


    Sorry, I haven't the faintest idea what you're driving at, unless you're
    already talking about the symref -- and that comes in the next line.
    Maybe you just want me to deref to a temp variable before proceeding.
    I'm content to jam it all in one line.

    I'm from the days when absolutely everything had to be declared and
    reserved; every single operation was one instruction at a time.
    Sometimes one machine-language instruction actually ran to more than one
    line of code.

    I'd spend a week writing the equate table before typing the first line
    of executable -- and that would be at address 0, and I knew it was at 0,
    and I knew it had to be the system boot because when the power came on,
    the processor would start at 0, god willin ana river doan rise. If I
    wanted to loop, I had to declare and maintain the whole structure and
    no, I didn't trust the assembler to put things where I wanted. I'd
    assemble and dump it onto 132-col greenbar and check the hex. Up to me
    which register to use for the count and all my fault if I picked wrong.
    Sometimes I patched shipping firmware directly in hex -- code, not
    constants. I don't do that anymore.

    When I iterate over an array without knowing, anywhere, the loop
    iterator even exists I get a little woody. :p You see the verbose
    version of my code. Yes, I know, it's a sin. Sorry.

    > XC> &{"report_" . lc($_)} ($ref->{SETS}{$_})


    >...make a dispatch table...


    Oooh, sorry, but I sort of disagree. Maybe better than blatantly
    constructing the sub name out of sticks and pebbles on the fly but a
    jump table is a jump table, no matter what you call it. I'm looking for
    more elegance.

    Please relax; I have no intention of really using what I call a
    "calculated jump". As I posted, that's the first thing to break. Last
    time I tried that for a client on a serious project, was 20 years ago
    and I thought I was cool. I only did it because it could be done -- and
    because nobody had ever educated me as to why it might be risky.

    Also, please breathe easy about the multiple objects. I'm off the clock
    on this; it's a personal project. I can afford to go in the wrong
    direction for a long time, learn something while I'm there, and
    mercilessly refactor until the chrome gleams.

    Still, thank you for your concerns.

    Xiong
    --
    Xiong Changnian
    xiong102ATxuefangDOTcom

    --
    Posted via a free Usenet account from http://www.teranews.com
     
    Xiong Changnian, Feb 6, 2007
    #12
  13. Re: Multiple Classes per File...

    In article <Xns98CF996514C0Casu1cornelledu@127.0.0.1>,
    "A. Sinan Unur" <> wrote:

    > You are sounding cranky and stubborn...


    I'm really very sorry if it appears that way to you. I *am* a cranky,
    stubborn old man but I try not to act that way in every circumstance.

    If I qualify the module with Jam::Band in package, use, and use base, it
    works. I didn't see why, *instead*, as I've been doing, I can sometimes
    call it merely Band.

    My explanation is that use refers to the file itself, so needs the
    directory relative to my script; use base and package refer to the
    package/class instead and require no such qualification.

    It makes sense, then, that I was able to declare packages/classes Tuba,
    Drum, and Violin all in the file Guts.pm. I use Jam::Guts because there
    is no file Jam::Tuba. I might (somewhere) use base qw(Tuba Drum Violin)
    if for some mad reason, I want to inherit Moog from all three mommies.

    If this isn't so, no matter; the vehicle takes me where I want to go and
    my elbow is comfortably removed from the big red button. I'm entirely
    satisfied with the answers I was given.

    Thanks again for the suggestions.
    --
    Xiong Changnian
    xiong102ATxuefangDOTcom

    --
    Posted via a free Usenet account from http://www.teranews.com
     
    Xiong Changnian, Feb 7, 2007
    #13
  14. Xiong Changnian

    Uri Guttman Guest

    Re: Multiple Classes per File and use

    >>>>> "XC" == Xiong Changnian <> writes:

    XC> But if I can use Jam::Band and use base Jam::Band if I package
    XC> Jam::Band, then I will sleep better. Thanks.

    XC> In article <>,
    XC> Uri Guttman <> wrote:

    >> use named variable when possible.
    >> it makes for more easily understood code.


    XC> Sorry, I haven't the faintest idea what you're driving at, unless you're
    XC> already talking about the symref -- and that comes in the next line.
    XC> Maybe you just want me to deref to a temp variable before proceeding.
    XC> I'm content to jam it all in one line.

    you used a for loop with the implied use of $_ as the loop variable. it
    is better to use a named lexical variable instead like this:

    for my $foo ( @bars ) {

    it makes the code easier to understand since the loop body will have
    that name to help document it. i only use $_ in map/grep where it is
    required and in special cases where it works better.

    XC> I'm from the days when absolutely everything had to be declared and
    XC> reserved; every single operation was one instruction at a time.
    XC> Sometimes one machine-language instruction actually ran to more than one
    XC> line of code.

    you don't have to tell us your background regarding declarations. most
    of the regulars here know multiple langs and know all about this area.


    XC> When I iterate over an array without knowing, anywhere, the loop
    XC> iterator even exists I get a little woody. :p You see the verbose
    XC> version of my code. Yes, I know, it's a sin. Sorry.

    but you didn't use an explicit loop iterator variable but the default
    $_.

    XC> &{"report_" . lc($_)} ($ref->{SETS}{$_})

    >> ...make a dispatch table...


    XC> Oooh, sorry, but I sort of disagree. Maybe better than blatantly
    XC> constructing the sub name out of sticks and pebbles on the fly but a
    XC> jump table is a jump table, no matter what you call it. I'm looking for
    XC> more elegance.

    XC> "calculated jump". As I posted, that's the first thing to break. Last
    XC> time I tried that for a client on a serious project, was 20 years ago
    XC> and I thought I was cool. I only did it because it could be done -- and
    XC> because nobody had ever educated me as to why it might be risky.

    this is very wrong in several ways. it is a symref which you said you
    don't want to do and no one recommends that you do. it is not testing if
    the sub exists or not. it is a potential source of future bugs (all
    synrefs are). it uses the symbol table as a general purpose hash when it
    should be only used to mung the symbols. you can make the dispatch table
    a lexical hash whics is safer (more private) and you can pass it around
    or store it in something else like an object (can't be done with symrefs
    since they are global). so there are many reasons to use a dispatch
    table and none that support using symrefs there. you asked for advice on
    coding and this is one answer you shouldn't ignore regardless of your
    taste and style. it is BAD coding to use symrefs if there is a better
    way to do it. that is why use strict disallows them.

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
     
    Uri Guttman, Feb 7, 2007
    #14
  15. Xiong Changnian

    Uri Guttman Guest

    Re: Multiple Classes per File...

    >>>>> "XC" == Xiong Changnian <> writes:

    XC> In article <Xns98CF996514C0Casu1cornelledu@127.0.0.1>,
    XC> "A. Sinan Unur" <> wrote:

    >> You are sounding cranky and stubborn...


    XC> I'm really very sorry if it appears that way to you. I *am* a cranky,
    XC> stubborn old man but I try not to act that way in every circumstance.

    XC> If I qualify the module with Jam::Band in package, use, and use base, it
    XC> works. I didn't see why, *instead*, as I've been doing, I can sometimes
    XC> call it merely Band.

    XC> My explanation is that use refers to the file itself, so needs the
    XC> directory relative to my script; use base and package refer to the
    XC> package/class instead and require no such qualification.

    you don't understand use, package names and modules yet. i will try to
    explain them better. first off, the argument to use, a package name and
    a module name/path are officially unrelated. you can use any value in
    any of those places if you know what you are doing. there are ways they
    are related and with conventions too and if you take advantage of them
    they work well together.

    package command name is just the default symbol table space for all the
    code that follows it until the next package command or the end of the
    file/eval block. this means you can put the same package name in
    multiple modules and multiple package names in one module. a package
    command has no other purpose but to set the default name for unqualified
    globals. if you fully qualify all globals in use you would never need a
    package command.

    a module name (really just a file name) is just that, the name of a
    physical module or file. it has nothing official to do with its contents
    or any package names inside the file. the module name is just used to
    locate and load a particular source file with a .pm suffix (i am
    ignoring .so and related c libs here). if a module name is in some
    subdirs like Foo/Bar/Util.pm those directories are not part of the
    file name but need to be used to find the module.

    a require command will take a class name Foo::Bar::Util and break up the
    :: parts and convert the names into file system specific dirs, searches
    OINC for it, opens that file (it adds a .pm suffix) if found and loads
    it into perl. this is done at runtime and no symbol table munging
    (exporting) is done for you. the module itself can do what it wants in
    mainline code which will run then. require is executed at runtime so it
    is good for loading modules on demand but not for loading symbols you
    need in the current code.

    a use command is a combination of a require and a call to the import
    method. here is where things get interesting with module names and
    package names. use does the same lookup of the file as require (note
    that this can be case insensitive on some file systems which is a
    classic newbie bug) and loads the file. but then it will take the class
    name it was passed and call the class method import and pass it any
    other args on the use line. in the common OO case, no import is found
    since you don't export methods or symbols in pure OO. in typical
    procedural modules some form of Exporter (there are a few now) will be
    inherited and have an import method which gets called. it locates the
    @EXPORT/_OK and related variables in your package and exports symbols
    into the package with the use line as requested. note that it calls
    import on ONLY one name, the class name passed to use. if you have more
    than one package name in a module and one of them is the same class name
    as called by use, only that package's import (usually inherited as i
    said but it can be an explicit sub) is called. this is where some get
    confused about multiple package names in a module and things not being
    exported as expected.

    finally we come to use base. base.pm is a simple pragma that saves a
    little work when using inherited classes. it does two things, it loads
    the requested module (but not with use which is fine as this is meant
    for pure OO modules) and it also unshifts the classname into the current
    package's @ISA (which controls method lookups for inheritance). so the
    module name and class name when you do use base must agree if you want
    the proper file to be loaded and to properly inherit from it. you can't
    just pick names that seem right and do use base and it will work. your
    case seems to be like that, you didn't make sure the module path and the
    class names agreed when you did use base. in your case with all those
    classes in one file and they all inherit from the same set, it would be
    cleaner to just to a use at the top of the file and do this inside each
    package:

    # top of file and one time only. loads the file once which is all that
    # is needed.

    use Parent::Classes ;


    # do this for each package in the file as needed
    # doesn't load any files but sets up inheritance any way you want.
    # note that the parent name isn't the same as the file loaded as i
    # wanted to show how they can be different

    package My::Foo ;

    BEGIN{ our @ISA ; unshift 'Parent::Class::Foo, @ISA }

    note that the use line can specify ANY module it wants and you can then
    inherit separately in each class in the file. use base won't allow this
    separation but it is designed for the common case where the package
    names and files agree.

    XC> It makes sense, then, that I was able to declare packages/classes
    XC> Tuba, Drum, and Violin all in the file Guts.pm. I use Jam::Guts
    XC> because there is no file Jam::Tuba. I might (somewhere) use base
    XC> qw(Tuba Drum Violin) if for some mad reason, I want to inherit
    XC> Moog from all three mommies.

    i don't exactly get that but i think you should understand my explanation
    above. you need to understand how these names and calls relate to each
    other and not guess and thrash about.

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
     
    Uri Guttman, Feb 7, 2007
    #15
  16. Xiong Changnian

    Uri Guttman Guest

    Re: Multiple Classes per File and use

    >>>>> "MD" == Michele Dondi <> writes:

    MD> On Wed, 07 Feb 2007 15:51:57 -0500, Uri Guttman <>
    MD> wrote:

    >> you used a for loop with the implied use of $_ as the loop variable. it
    >> is better to use a named lexical variable instead like this:
    >>
    >> for my $foo ( @bars ) {
    >>
    >> it makes the code easier to understand since the loop body will have
    >> that name to help document it. i only use $_ in map/grep where it is
    >> required and in special cases where it works better.


    MD> Oh c'mon! This is just *so* controversial... even slightly
    MD> flame-baiting... I use $_ all the time in loops, provided they're
    MD> short enough. If possible I cast them in a statement modifier form,
    MD> even. If code is self explanatory it is... err, well, self
    MD> explanatory. Of course I would never recommend to use $_ with a for
    MD> loop having a main block of 25 lines!!

    i wouldn't call it controversial or flame baiting. you can disagree with
    it but most style guides (PBP included) recommend named variables
    whenever possible. sure it is a style issue but i am a strong advocate
    of named variables as part of an overall style. and i emphasize choosing
    quality names which makes it work even better.

    XC> "calculated jump". As I posted, that's the first thing to break. Last
    XC> time I tried that for a client on a serious project, was 20 years ago
    XC> and I thought I was cool. I only did it because it could be done -- and
    XC> because nobody had ever educated me as to why it might be risky.
    >>
    >> this is very wrong in several ways. it is a symref which you said you
    >> don't want to do and no one recommends that you do. it is not testing if

    MD> [snip]

    MD> I wholeheartedly agree with you, but some details, including the
    MD> "calculated jump" one above make me suspect that the OP really
    MD> misunderstood the meaning of "dispatch table", in which case I renew
    MD> the invite for him to look it up.

    well, i took calculated jump as the symref since that is a calculated
    name of the sub to call. but later the OP seemed to agree with me so i
    am confused as to whether he is going to use a dispatch table.

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
     
    Uri Guttman, Feb 8, 2007
    #16
  17. Xiong Changnian

    Uri Guttman Guest

    Re: Multiple Classes per File and use

    >>>>> "MD" == Michele Dondi <> writes:

    MD> On Thu, 08 Feb 2007 12:56:45 -0500, Uri Guttman <>
    MD> wrote:

    >> i wouldn't call it controversial or flame baiting. you can disagree with
    >> it but most style guides (PBP included) recommend named variables
    >> whenever possible. sure it is a style issue but i am a strong advocate
    >> of named variables as part of an overall style. and i emphasize choosing
    >> quality names which makes it work even better.


    MD> Well, PBP (and Perl::Critic) is somewhat controversial too. Some
    MD> knowledgeable and respectful Perl hackers beg to differ on some
    MD> specific points.

    i was one of the tech editors of PBP and i disagree with many
    points. but i do agree on using names vars where possible (some
    exceptions do apply). damian explicitly states that PBP is meant to be a
    possible set of rules and not an absolute set. you can pick and choose
    and make up your own but consistancy in style is the goal, not a
    particular style. and you should have at least a reason why any style
    point is chosen and not some random default reason. good style has logic
    behind it that defends it. i say named vars make the code more
    readable as names help document what is being worked upon vs $_ which
    has no such benefit. $_ can be set far enough away as to make it harder
    to track its meaning. it can also cause action at a distance as it is a
    global (though it can be localized by for or explicitly). just having
    named vars be lexicals is a win too.

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
     
    Uri Guttman, Feb 9, 2007
    #17
    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.

Share This Page