Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

About inheritence ? and Autoload ?

by lepetitalbert (Monsignor)
on Nov 24, 2009 at 23:01 UTC ( #809222=perlquestion: print w/ replies, xml ) Need Help??
lepetitalbert has asked for the wisdom of the Perl Monks concerning the following question:

Hello esteemed Monks,

I'm looking for some enlightenment about some 00 concepts.
given :

package Test; sub new { my $class = shift; my $item = {}; print "DEBUG : creating object in " . __PACKAGE__ . "\n"; bless $item , $class; return $item; } 1;

and :

package Test::Command; use strict; use warnings; use Test; use vars qw(@ISA); @ISA = qw(Test); sub new { my $item = shift; my $command = shift; my $class = ref( $item ) || $item; my $self = bless $item->SUPER::new(), $class; print "DEBUG : handling command $command in " . __PACKAGE__ . "\n" + if ( $command ); } 1;

running :

#!/usr/bin/perl use strict; use warnings; use lib 'lib'; use Test; use Test::Command; $|=1; my $test_command = Test::Command->new(@ARGV);

produces :

DEBUG : creating object in Test DEBUG : handling command test_command in Test::Command

question 1 :
why does

my $test_command = Command->new(@ARGV);

not work ?
and question 2 :

in Test::Command I'd like to check if there's a

Test::Command::$command

module and if yes execute something like this

Test::Command::$command->handle_output()

Do I need some AUTOLOAD Voodoo ? in Test.pm ?

Any hints, pointers, examples and even solutions are welcome !

P.S : I already read the common OOtuts (several times), but it's still not clear in my tired neuron.

Thanks !

Have a nice day

"There is only one good, namely knowledge, and only one evil, namely ignorance." Socrates

Comment on About inheritence ? and Autoload ?
Select or Download Code
Re: About inheritence ? and Autoload ?
by ikegami (Pope) on Nov 24, 2009 at 23:38 UTC

    why does my $test_command = Command->new(@ARGV); not work ?

    How does it "not work"? ( Oops, thought it said Test->new. You never defined Command::new )

    I'd like to check if there's a Test::Command::$command module

    my $pkg = "Test::Command::$command"; ( my $mod = $pkg ) =~ s{::}{/}g; $mod .= '.pm'; my $exists = eval { require $mod };

    and if yes execute something like Test::Command::$command->handle_output()

    ... $pkg->handle_output();

    By the way, Test::Command::new re-blesses the object for nothing and could use some cleanup:

    sub new { my $class = shift; my $command = shift; my $self = $class->SUPER::new(); print "DEBUG : handling command $command in " . __PACKAGE__ . "\n" if ( $command ); }
Re: About inheritence ? and Autoload ?
by kyle (Abbot) on Nov 25, 2009 at 03:23 UTC
    my $test_command = Command->new(@ARGV);

    My guess is it doesn't work because there's no "Command" package with a "new" sub in it. In Perl, there's no automatic relationship between Test and Test::Command. They're just two names like Foo and Bar.

Re: About inheritence ? and Autoload ?
by spx2 (Chaplain) on Nov 25, 2009 at 08:19 UTC
Re: About inheritence ? and Autoload ?
by pajout (Curate) on Nov 25, 2009 at 08:33 UTC
    About namespaces and inheritance:

    Namespaces, like "Animal::Dog", are just names, as was written before. Inheritance is defined differently, but it is good habit to create namespaces related with inheritance, for instance:

    package Animal; #parent class, in file lib/Animal.pm sub new { return bless {}, shift; } sub sound { die "cannot call this method on class '".ref(shift)."'"; } sub output_sound { my ($self, $what) = @_; print $what."\n"; } 1; package Animal::Dog; #desc. of Animal, lib/Animal/Dog.pm use base 'Animal'; sub sound { my ($self) = @_; $self->output_sound("haf"); } 1; package Animal::Dog::Sheepdog; #desc. of Dog #lib/Animal/Dog/Sheepdog.pm use base 'Animal::Dog'; sub guard { my ($self, $flock) = @_; #do something } 1; package Animal::Pig; #other descendant use base 'Animal'; sub sound { my ($self) = @_; $self->output_sound("khro"); } 1;
    Now you can create some instance of animal :>) by this way:
    use Animal::Dog::Sheepdog; my $helper = Animal::Dog::Sheepdog->new(); #Once you have an instance, you can call it's methods by this way: $helper->sound;
    Do not hesitate to ask some questions, I had been confused in the same manner. Just note: that code is not tested, it really should have strictings in every module...

      Hello dear Monks,

      Thank you all for you help !

      ikegami, the error was

      Can't locate object method "new" via package "Command" (perhaps you fo +rgot to load "Command"?) at ./test line 13

      and you said

      You never defined Command::new

      ? here I bug :
      I have a package Test::Command with a sub new, and a use Test::Command;
      Why is Command new not defined ?

      kyle,

      But I'd like some automatic relationship between Test and Test::Command

      Is that a @ISA or inheritence question

      spx2, I read stuff on Moose too and will probably use it, but I thought I'll try to understand first the 'manual' way.

      pajout, I think my understanding bug is somwhere in your example but still don't where ! I'll play with it.
      why can't you use

      use Animal::Dog::Sheepdog; my $helper = Sheepdog->new();

      Thanks again.

      Have a nice day.

      "There is only one good, namely knowledge, and only one evil, namely ignorance." Socrates
        The name of the module is 'Animal::Dog::Sheepdog', so if you try my $helper = Sheepdog->new();, Perl has no clue which module do you mean, respectively, Perl says Sheepdog module is not used. Imagine situation when both Foo and Bar::Foo are used, you have to distinguish in your code which object you want to create.

        Update: It is just about naming, not about inheritance. Inheritance is (in my example) defined by use base.

        If you want to use the current package as the base name of some other package, you could do something like this:

        my $subpackage = __PACKAGE__ . '::Command'; my $test_command = $subpackage->new(@ARGV);

        You could also make a module that installs this behavior into every package. Here's a demonstration:

        sub UNIVERSAL::subpackage { join '::', @_ } package Foo::Command; sub wow { print "I am: ", __PACKAGE__, "\n" } package Foo; sub check { __PACKAGE__->subpackage( 'Command' )->wow() } package main; Foo->check(); __END__ I am: Foo::Command

        In Real Code, you'd put the sub UNIVERSAL::subpackage part into another module which you then use from every package that you want to have that behavior. While "__PACKAGE__->method( 'Blah' )" is a lot longer than just "Blah", it also carries a bit more meaning.

        Is that closer to what you want?

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://809222]
Approved by keszler
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (14)
As of 2014-10-21 15:58 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    For retirement, I am banking on:










    Results (105 votes), past polls