snoopy20 has asked for the wisdom of the Perl Monks concerning the following question:

Hi All. I'm busy converting my CMS over to OO, exactly why I'm not sure but I'm sure the grass is greener on the other side. I have hit my first issue, and having read the guides I'm unsure on how to resolve it.

I have a module 'igaro.pm', which loads critical modules in the 'core' folder. These modules are instantiated into the parents $self hash. However many modules will need access to the parents hash, in order to get at a piece of data.

The only way I can see on how to fix it would be to pass the required hash values with the call to the child, but this seems messy. Here's my code so far…

package igaro; use 5.6.0; use strict; use warnings; our $VERSION = '1.00'; sub new { my $class = shift; my %params = @_; my $self = bless { uri => undef, dbh => undef, form => undef, cookies => undef, data => {}, action => $params{settings}{defaultfunction}, settings => delete $params{settings}, language => undef, date => undef, cache => {} } => $class; $self->{data}{template}='main'; return $self; } sub exec { my $self = shift; $self->{data} = {}; use igaro::core::dbh::connection; $self->{dbh} = igaro::core::dbh::connection->new(type=>$self->{set +tings}{database}{type}, name=>$self->{settings}{database}{name}, pass +word=>$self->{settings}{database}{password}, username=>$self->{settin +gs}{database}{username}, connect=>$self->{settings}{database}{connect +} ) if undefined $self->{dbh}; use igaro::core::language::cache; $self->{language} = igaro::core::language::cache->new if undefined + $self->{language}; use igaro::core::date::now; $self->{date} = igaro::core::date::now->new(); use igaro::core::uri::env; $self->{uri} = igaro::core::uri::env->new(); $self->{action} = $self->{uri}->{i} if $self->{uri}->{i}; use igaro::core::form::env; $self->{form} = igaro::core::form::env->new(); use igaro::core::cookies::env; $self->{cookies} = igaro::core::cookies::env->new(); use igaro::core::usergroups::cache; $self->{cache}{usergroups} = igaro::core::usergroups::cache->new(d +bh=>$self->{dbh}->get) if undefined $self->{cache}{usergroups}; use igaro::core::session::load; $self->{session} => igaro::core::session::load->new(cookie=>$self- +>{cookies}->get('session'), dbh=>$self->{dbh}->get); } 1;

Example; on igaro::core::session::load, I passed the cookie and the dbh handle. Can the child not get it itself?

Or do I pass a copy of the parent, like:

$self->{session} => igaro::core::session::load->new(parent=>$self)

Replies are listed 'Best First'.
Re: OO Conversion Query - Sharing Data
by Corion (Patriarch) on Apr 11, 2013 at 14:24 UTC
    ... if undefined $self->{dbh};

    What is this undefined function? Are you sure that the code you showed bears any semblance to what you run?

    I would check what $self->{cookies} = igaro::core::cookies::env->new(); returns, and whether it actually contains any cookies.

    Then, I would check that $self->{cookies}->get('session') actually returns what the browser sent.

    If this is in relation to The most powerful CMS developed in Perl (not spam, sounds that way), I would compare the differences in cookie handling between the old and the new implementation. Maybe you have a regression test suite that checks that handing out a session cookie works?

Re: OO Conversion Query - Sharing Data
by educated_foo (Vicar) on Apr 11, 2013 at 16:06 UTC
    exactly why I'm not sure but I'm sure the grass is greener on the other side.
    Here's your problem, unless its a "because the boss wants it" situation. If you're fine with it now, why shuffle the code to make it more fashionable? If you have problems with it now, what OO techniques will ameliorate them, and how?
      Hi again, please ignore the obvious errors such as 'undefined', I am at the very early stages of porting.

      Reasoning

      'igaro' doesn't really need OO porting as per say, the only reason I'm doing it is to make the code less fragile. I think.

      Another reason is my relative lack of OO experience, and I have a tech interview on Tuesday. I'm bringing myself up to speed the hard way. :)

      The code

      In essence I'd coded so that one function = one file. It was rare for this to be anything different, which of course diminished the need for employing classes.

      Now I'm converting the common functions, but the logic seems a little daft. Before I'd require the file and stick it into the namespace as 'igaro_xxx_xxx'. Now I'm instantiating the function into $self->{common}{xxx_xxx} and the other functions that used to call &igaro_xxx_xxx will have to do $self->{common}{xxx_xxx}->exec();

      I have worked around the sharing of parent data by sending a reference to the parent through the params, like $self->{common}{xxx_xxx}->exec(parent=>$self);

      Previously all the data was stored in several global hashes like %DATA.

      My brain has just about fried itself.

        $self->{common}{xxx_xxx}->exec(parent=>$self); Ew! It seems like you're trying to implement OO the C way in Perl. Writing an object system will teach you a lot about OO, but doing it in Perl results in some nasty code. You should look at bless for how to associate functions with an object in Perl. Basically, your global hash becomes $self, you bless it into a package, and you define your functions in that package. Then when you call them as $self->foo, $self gets passed as the first parameter.

        Then again, it seems like you already had a nicely modular system, so you may learn something from this exercise, but it won't help your code.

Re: OO Conversion Query - Sharing Data
by Anonymous Monk on Apr 12, 2013 at 07:37 UTC

    I have a module 'igaro.pm',

    FYI, that kind of goes against the informal naming convention , see perlmodlib if you're interested

      Thanks, but it's not an oo package that will be used by anything else.

        In that case, to make sure you never have to worry about conflicts, you might want to use Local::PackageName. That is the traditional (and traditionally reserved) namespace for local/internal code that won't go outside of your own use.

        Christopher Cashell