http://qs321.pair.com?node_id=867747


in reply to Re: Conditional inheritance strategy
in thread Conditional inheritance strategy

Hi BrowserUk,

You are right in your assumptions. My::XML and My::JSON only provide data to the inherited class, no other methods are used (except methods internally used by My::XML or My::JSON).

If so, if you instantiated an instance of the relevant XML or JSON class to just parse the source data; then retrieved the data required by My class; and then allowed the parse instance to be reclaimed as soon as the initialisation of a new My class instance was complete; then your My class instances might be individually smaller. And possibly more efficien,t because of shorter method resolution paths.

Sorry if I misunderstand your. Are you suggesting the following?:

Package My:

sub new { my ($class,%args) = @_; my $data; if ($args{source} eq 'xml') { require My::XML; # @ISA = qw/My::XML/; $data = My::XML->new(%args); } elsif ($args{source} eq 'json') { require My::JSON; # @ISA = qw/My::JSON/; $data = My::JSON->new(%args); } my $self = bless \%{$data}, $class; return ($self); } # rest of methods sub method1 { ... } sub method2 { ... } 1;

Package My::XML

package My::XML; use XML::Simple qw(:strict); sub new { my ($class,%args) = @_; my $self = bless {}, $class; $self->_init(); return $self; } sub _init { # Code to read the data from XML source } 1;

Same for My::JSON

Thank you very much for your comments

citromatik

Replies are listed 'Best First'.
Re^3: Conditional inheritance strategy
by BrowserUk (Patriarch) on Oct 27, 2010 at 15:13 UTC
    Are you suggesting the following?: [ ... CODE ... ]

    Yes, that is pretty much what I was suggesting--but only because I assumed that the XML & JSON modules contained classes. Ie. That there was a purpose in inheriting from them because they had local state and more methods than just _init().

    With your confirmation that they only contain one _init() subroutine each--although you are calling them as methods--personally, I can see no reason not to simply move the two _init() routines into your My package (with different names), and drop the extra packages.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      With your confirmation that they only contain one _init() subroutine each--although you are calling them as methods--personally, I can see no reason not to simply move the two _init() routines into your My package (with different names), and drop the extra packages.

      Well, the main reason is modularity:

      • Class My contains methods to deal with a particular kind of data (a kind of trees if that matters) regardless how I feed data to these objects
      • My::XML contains, well, code that feeds data coming from a particular source. Although it is true that only _init is used by My, there are other functions/methods that are called by _init (all related with cleaning and parsing the data).
      • The same for My::JSON.

      For me, it makes a lot of sense to separate code that reads data in a special format to feed the objects from code that manage the objects.

      citromatik

        Well, the main reason is modularity:

        The purposes of modularity are: reuse, and separation of concerns.

        The question to ask yourself is can either those modules, who's sole purpose is to initialise instances of this particular class, ever be used without the class module?

        Based on your description, the answer is no. That means those one function libraries are "close coupled" to their parent. They can have no purpose without their parent; nor the parent without (at least one) of them.

        There is another acceptable use of modularity. That of breaking up large single files into manageable bits. Generally, this practice shouldn't be needed, because components naturally break down into manageable sized-files, but sometimes it makes sense to introduce artificial granularity.

        But in your case, without knowing which XML/JSON readers you are using, it is hard to see that populating a hash from a file in one or the other of those formats could take much more than 10 or 20 lines each. Separating out of 40 lines from the main file, no matter how big it is, will make no difference at all to its manageability.

        At the extreme, almost every individual file becomes one line of executable code. And the few that aren't then become meta code dealing with how to manage those one-function/one-line files. You end up with 100 lines of executable code, spread across 50 files. 50 of those lines are single string compares, and the other 50 are a bunch of hideously, slow string evals, who's only purpose is to load the the 50 string compares.

        I'm not suggesting that you'd go that far, but do think carefully before arbitrarily breaking out lumps of code into separate files and name-spaces.

        Anyway, you asked the question, I've added my perspective to the pile of replies. Now you can choose your favourite, or ignore them all :)


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.