![]() |
Single-File Inheritance
I am trying to do the Right Thing and write a data-processing program
using lofty Object-Oriented principles, instead of my usual lazy procedural ways, but I am having trouble with putting multiple class packages into one file. I started out using just one file for convenience while I develop a framework, and then was planning on splitting the file into separate modules once I got the basics working. I am trying to read some data files that have the same format in the first 6 lines, then have different data records in subsequent lines. I thought I would write a parent class that reads the header lines, then child classes to read and parse subsequent lines. Here is the result: % cat single.pl #!/usr/local/bin/perl use strict; use warnings; my $file = ConfigFile->new(); # line 5 package DataFile; sub new { my($class) = shift; my $self = {}; bless $self, $class; return $self; } package ConfigFile; our @ISA = qw( DataFile ); % perl single.pl Can't locate object method "new" via package "ConfigFile" at single.pl line 5. % perl -v This is perl, v5.10.1 (*) built for darwin-2level If I put the packages in separate files, it works (compiles and runs). I am almost sure that I have done this type of thing before, and I can't find any documentation that says I can't. Should I be able to put multiple packages in a single file and use inheritance for two of those packages? Thanks. -- Jim Gibson |
Re: Single-File Inheritance
Jim Gibson <jimsgibson@gmail.com> wrote:
> > % cat single.pl > #!/usr/local/bin/perl > use strict; > use warnings; > > my $file = ConfigFile->new(); # line 5 > ..... > > package ConfigFile; > our @ISA = qw( DataFile ); > % perl single.pl > Can't locate object method "new" via package "ConfigFile" at single.pl > line 5. The creation of the @ISA alias occurs at compile time (I think), but the assignment to @ISA happens only at run time when that line is encountered. At the time line 5 is executed, the ISA assignment line has not yet be run in the runtime, so has not yet taken place and @ISA is empty. You can wrap the @ISA assignment in a BEGIN block to force it to happen at compile time, or you can move your main code to be below the package code. Xho -- -------------------- http://NewsReader.Com/ -------------------- The costs of publication of this article were defrayed in part by the payment of page charges. This article must therefore be hereby marked advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate this fact. |
Re: Single-File Inheritance
On Tue, 17 Jan 2012 17:08:50 -0800
Jim Gibson <jimsgibson@gmail.com> wrote: > package ConfigFile; > our @ISA = qw( DataFile ); Rather than manually stuff @ISA, I'd use 'parent' with the -norequire option: package ConfigFile; use parent -norequire DataFile; ... |
Re: Single-File Inheritance
In article <20120117203145.805$rp@newsreader.com>, <xhoster@gmail.com>
wrote: > Jim Gibson <jimsgibson@gmail.com> wrote: > > > > % cat single.pl > > #!/usr/local/bin/perl > > use strict; > > use warnings; > > > > my $file = ConfigFile->new(); # line 5 > > > .... > > > > package ConfigFile; > > our @ISA = qw( DataFile ); > > > % perl single.pl > > Can't locate object method "new" via package "ConfigFile" at single.pl > > line 5. > > The creation of the @ISA alias occurs at compile time (I think), but the > assignment to @ISA happens only at run time when that line is encountered. > > At the time line 5 is executed, the ISA assignment line has not yet > be run in the runtime, so has not yet taken place and @ISA is empty. > > You can wrap the @ISA assignment in a BEGIN block to force it to happen at > compile time, or you can move your main code to be below the package code. Thanks for the explanation. That works. -- Jim Gibson |
Re: Single-File Inheritance
In article <4f16d2bb$5$fuzhry+tra$mr2ice@news.patriot.net>, Seymour J.
<spamtrap@library.lspace.org.invalid> wrote: > In <170120121708505710%jimsgibson@gmail.com>, on 01/17/2012 > at 05:08 PM, Jim Gibson <jimsgibson@gmail.com> said: > > >I am trying to do the Right Thing and write a data-processing program > >using lofty Object-Oriented principles, instead of my usual lazy > >procedural ways, > > You have to carve the bird at the joints. > > >I am trying to read some data files that have the same format in the > >first 6 lines, then have different data records in subsequent lines. > >I thought I would write a parent class that reads the header lines, > >then child classes to read and parse subsequent lines. > > Why? Why not a generic parent class and child classes for header lines > and for each category inferred from the header? I think that is what I am trying to do. Perhaps I could explain it better by saying "write a parent class that has methods to read the header lines, and child classes that have specialized methods to read and parse subsequent lines." File category is actually derived from the file name, not the contents of the header lines. > > >my $file = ConfigFile->new(); # line 5 > > Shouldn't that be > > my $file = DataFile->new(); # line 5 I don't think so. DataFile is the parent class and doesn't have any methods to interpret the data. ConfigFile is a child class that reads and parses config files (in this simple, made-up example). I won't ever instantiate an object of the DataFile class. I will instantiate a ConfigFile object and call new() and open() methods on that object, which will cause DataFile::new() and DataFile::open() to be called, since ConfigFile inherits new() and open() from DataFile. > > >If I put the packages in separate files, it works (compiles and > >runs). > > Could yuou show skeletal versions of the individual files? The contents of the files are irrelevant for my problem, which happens before the files are opened. But thanks. -- Jim Gibson |
Re: Single-File Inheritance
In article <20120118193313.3198727a@columbia>, David Precious
<davidp@preshweb.co.uk> wrote: > On Tue, 17 Jan 2012 17:08:50 -0800 > Jim Gibson <jimsgibson@gmail.com> wrote: > > > package ConfigFile; > > our @ISA = qw( DataFile ); > > Rather than manually stuff @ISA, I'd use 'parent' with the -norequire > option: > > package ConfigFile; > use parent -norequire DataFile; > ... Thanks. This works: use parent -norequire, 'DataFile'; although I don't see any advantage over 'our @ISA = ...' -- Jim Gibson |
Re: Single-File Inheritance
In article <4f178e61$4$fuzhry+tra$mr2ice@news.patriot.net>, Seymour J.
<spamtrap@library.lspace.org.invalid> wrote: > In <180120121619571440%jimsgibson@gmail.com>, on 01/18/2012 > at 04:19 PM, Jim Gibson <jimsgibson@gmail.com> said: > > >I think that is what I am trying to do. > > No. > > >Perhaps I could explain it better > > That's what you wrote the first time; it's not what I'm suggesting. OK. Then I guess I don't understand your suggestion. > >by saying "write a parent class that has methods to read the > >header lines, and child classes that have specialized methods to read > >and parse subsequent lines." > > Why not have the methods for header lines in child classes? Because the 6 header lines are the same for all types of files. I have written an open() method in the parent class that given the file path, opens the file, reads the first 6 lines, and saves the data therein. It leaves the file open at the 7th record. The open() method is implemented in the parent class and inherited by the child classes. What would be the point in duplicating the open method identically in all the child classes? Thanks for your input. Sorry I don't understand your points. -- Jim Gibson |
Re: Single-File Inheritance
Ben Morrow <ben@morrow.me.uk> writes:
> Quoth Jim Gibson <jimsgibson@gmail.com>: >> <davidp@preshweb.co.uk> wrote: >> > >> > Rather than manually stuff @ISA, I'd use 'parent' with the -norequire >> > option: >> > >> > package ConfigFile; >> > use parent -norequire DataFile; >> > ... >> >> Thanks. This works: >> >> use parent -norequire, 'DataFile'; >> >> although I don't see any advantage over 'our @ISA = ...' > > It is, by design, equivalent to > > BEGIN { our @ISA = "DataFile" } > > and the fact the assignment happens at compile time can be important. > > For the few circumstances where keeping a class in the 'wrong' file is a > good idea, I wouldn't bother with 'parent' and would just use the BEGIN > above. 'parent' is useful in the normal case, where you need to load the > parent class as well as inherit from it. For a lot of not entirely trivial code I have written, this is actually the common case and not because classes reside in files which won't be found by the search algorithm which happens to be used by 'use' but because the dependencies among the classes themselves are too complex to enabling loading modules defining parent classes from the files defining dependent classes. In this case, I usually load all modules from the source files containing the main program and declare dependencies in the classes themselves. Morale: That someone has never seen code where separating loading of modules and declaring inheritance relationships was necessary doesn't exactly make that someone someone who is qualified to judge that this separation doesn't make sense. Minor gems: { no strict 'refs'; # This is more efficient than push for the new MRO # at least until the new MRO is fixed @{"$inheritor\::ISA"} = (@{"$inheritor\::ISA"} , @_); }; In plain English, this means 'this is a workaround for a bug in some other code' [which isn't used by default]. And this is - of course - an atrociously indefficient way to reinvent unshift. [rw@sapphire]~ $perldoc -f unshift unshift ARRAY,LIST Does the opposite of a "shift". Or the opposite of a "push", depending on how you look at it. Prepends list to the front of the array, and returns the new number of elements in the array. unshift(@ARGV, '-e') unless $ARGV[0] =~ /^-/; Note the LIST is prepended whole, not one element at a time, so the prepended elements stay in the same order. Use "reverse" to do the reverse. |
Re: Single-File Inheritance
Rainer Weikusat <rweikusat@mssgmbh.com> writes:
[...] > { > no strict 'refs'; > # This is more efficient than push for the new MRO > # at least until the new MRO is fixed > @{"$inheritor\::ISA"} = (@{"$inheritor\::ISA"} , @_); > }; > > In plain English, this means 'this is a workaround for a bug in some > other code' [which isn't used by default]. And this is - of course - > an atrociously indefficient way to reinvent unshift. It isn't unshift at all, of course, I just mistakenly assumed that it had to be doing something other than adding elements to the end of a list ... |
Re: Single-File Inheritance
Rainer Weikusat <rweikusat@mssgmbh.com> writes:
> Ben Morrow <ben@morrow.me.uk> writes: [...] >> For the few circumstances where keeping a class in the 'wrong' file is a >> good idea, Here's what the Camel book has to say on "using WRONG files" (NB: A copy of that resides on my bookshelf at home some please spare me the anti-scientific outcry this time): Sometimes folks are surprised that including a class in @ISA doesn't require the appropriate module for you. That's because Perl's class system is largely orthogonal to its module system. One file can hold many classes (since they're just packages), and one package may be mentioned in many files. But I guess that has also been 'deprecated' by someone meanwhile ... |
| All times are GMT. The time now is 08:53 AM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.