Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer

Learning how to use inheritance...

by kiat (Vicar)
on Oct 07, 2003 at 15:32 UTC ( #297315=perlquestion: print w/replies, xml ) Need Help??
kiat has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks,

I found some oo perl example code to show how inheritance works. The following is the code in its originality:
#!/usr/local/bin/perl -w package One; sub new { $class = shift; print "creating object of class $class\n"; bless {}, $class; } package Two; @ISA = ("One"); sub new { $class = shift; print "creating object of class $class\n"; bless {}, $class; } $one = One->new(); $two = Two->new();
Since there are two package names One and Two (corresponding to two classes), I'll need to save 'package One' as and 'package Two' as ''.

My question is, shouldn't there be a third file (one that's named say ?) that is being called when one executes the program? In order words, do I need to create a third file (shown below) in addition to the two pm files:
# use One; use Two; $one = One->new(); $two = Two->new(); # So, to execute the program, I type >perl
Another question I've is: What difference does '@ISA = ("One");' in make? I mean there's still a need to declare 'use One' in before it will execute. When I comment out '@ISA = ("One");' in, the code still runs.

I'm new to perl oo so please forgive my rather elementary questions ;)

Replies are listed 'Best First'.
Re: Learning how to use inheritance...
by broquaint (Abbot) on Oct 07, 2003 at 15:46 UTC
    My question is, shouldn't there be a third file (one that's named say ?
    For the purposes of demonstration, seperating the packages into seperate files isn't necessary, or even seperating the 'main' code for that matter. However, if you want to use the packages One and Two you will need to save them as a .pm files in the library path. As for the 'main' section of code, that could be saved to a file, or piped into STDIN or even in as commandline argument to -e. As ever TIMTOWTDI :)
    What difference does '@ISA = ("One");' in make?
    It means that any subroutines in One are inherited by Two (which wasn't demonstrated in your example) e.g
    { package One; sub new { bless [], shift } sub onefunc { print "$_[0] in One::onefunc" } package Two; @ISA = 'One'; } my $two = Two->new; $two->onefunc(); __output__ Two=ARRAY(0x80fba1c) in One::onefunc
    So as you can see from the output Two has inherited One's methods i.e it has access to them (but not vice versa, hence the word 'inheritence'). For more information on inheritence see. perlboot and perltoot.


Re: Learning how to use inheritance...
by Abigail-II (Bishop) on Oct 07, 2003 at 15:47 UTC
    Everything could be in one file, using two or three files don't magically do something other than creating lexical scopes.

    As for the assignment to @ISA, you are really assigning to @Two::ISA, and you are telling Perl that the class Two inherits the class One. A use statement doesn't set up any inheritance relationship - it just includes code (and run import() if there is one, but that's not relevant in this case).

    The fact that the code still runs if you omit the @ISA assignment is that you aren't using the inheritance. The class One has just one method: new, but that method is also defined in class Two. So, One has nothing that Two can delegate to.


Re: Learning how to use inheritance...
by CombatSquirrel (Hermit) on Oct 07, 2003 at 15:48 UTC
    Actually, you don't even need two files. The "real" program is just in a package called "main" (packages are largely file-independent). Try the following:
    #!perl -w package One; sub new { my $class = shift; print "creating object of class $class\n"; bless {}, $class; } package Two; @ISA = ("One"); package main; my $one = One->new(); my $two = Two->new();
    Your code in still runs after removing the @ISA array, because you are overriding the inheritance of the new method by redeclaring it in the second package. Just remove the @ISA part in the above code and you will see where it leads you ;-).
    Hope this helped.
    Entropy is the tendency of everything going to hell.
Re: Learning how to use inheritance...
by fglock (Vicar) on Oct 07, 2003 at 18:07 UTC

    "packages" organize the code into namespace units. This is what it looks without them:

    sub One::new { my $class = shift; print "creating object of class $class\n"; bless {}, $class; } @Two::ISA = ("One"); my $one = One->new(); my $two = Two->new(); # creating object of class One # creating object of class Two
Re: Learning how to use inheritance...
by kiat (Vicar) on Oct 08, 2003 at 09:31 UTC
    Thanks to all for helping with my perl oo and inheritance questions :)

    Let's say I choose the packages-in-different-files approach, is the following code correct (3 files, the first is named, the second and the third
    # package One; sub new { my $class = shift; print "creating object of class $class\n"; bless {}, $class; } 1; # package Two; @ISA = 'One'; 1; # use One; use Two; my $one = One->new(); my $two = Two->new();

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://297315]
Approved by broquaint
[ambrus]: Corion: as for that, I talked with schmorp, and looked a bit more at Prima
[ambrus]: Corion: from the docs, it definitely looks like it would be possible to write an AnyEvent driver for it using Prima::File and Prima::Timer.
[ambrus]: (I haven't found an idle event.)
[ambrus]: However, I also looked at the internals, and found two interesting things:
[marto]: stupid xpath question, I have a xpath copied from the browser, is the * wildcard supposed to work for IDs? e.g. '//*[@id="*"]/ div/div/header/p/a '?
[ambrus]: The main loop for unixish systems is in https://metacpan. org/source/ KARASIK/Prima-1. 49/unix/apc_app.c. It is a hand-rolled select loop, but also always spins at least once every 0.2 seconds for some reason.
[ambrus]: marto: no, not that way. if you just want to test for an existing id attribute, then write *[@id] , or you can match a regexp to the value of that attribute like *[@id=~/something/ ]
[marto]: ambrus, thanks I ended up going with '//*[starts- with(@id, "thread_")]...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (6)
As of 2016-12-08 10:50 GMT
Find Nodes?
    Voting Booth?
    On a regular basis, I'm most likely to spy upon:

    Results (140 votes). Check out past polls.