how to autovivify a package from a string

D

David Baird

Hi,

If I generate the code for an entire package, how can I then use or
require it? I want to autogenerate a bunch of classes for accessing
database tables, reading the structure of the table from the db and
then using that info to construct the class. Using Alzabo to analyse
the db, the code generation part is quite easy, but now I can't figure
out how to autovivify the packages into existence. All I can think of
is to write the code string to a file and then issue a standard 'use',
but is there a more elegant way to do this (i.e. without writing the
thing out to a file)?

Thanks,

David.
 
N

Nicholas Dronen

DB> Hi,

DB> If I generate the code for an entire package, how can I then use or
DB> require it? I want to autogenerate a bunch of classes for accessing
DB> database tables, reading the structure of the table from the db and
DB> then using that info to construct the class. Using Alzabo to analyse
DB> the db, the code generation part is quite easy, but now I can't figure
DB> out how to autovivify the packages into existence. All I can think of
DB> is to write the code string to a file and then issue a standard 'use',
DB> but is there a more elegant way to do this (i.e. without writing the
DB> thing out to a file)?

My naive answer is:

#!/usr/bin/perl

use warnings;
use strict;

my $p = <<EOP
package Foo;
sub Bar { "Baz" }
EOP
;

eval $p;
print Foo::Bar(), "\n";
__END__

There might be problems with your approach, but someone else will
have to tell you what they are. :)

Regards,

Nicholas
 
E

Eric Schwartz

Uri Guttman said:
ES> To the OP: If you can live without autovivification, the best answer I
ES> can come up with is to use a factory pattern to build the classes for
ES> you. It's not automatic, but it's nearly so.

and that makes little sense either. perl doesn't need most patterns as
it is a higher level language with many of those (silly) things built
in.

A pattern is simply a programming concept. Factory patterns make as
much (or as little, I suppose) sense in Perl as they do in any other
language. Just glancing at the inside of my _Design Patterns_ book,
most of them seem quite applicable to OO programs written in Perl.
if the OP would post again and clarify what the real problem is (not
their partial solution) i am sure we can help. but autovivification of
classes makes no sense.

I agree, more clarification would help here.

-=Eric
 
U

Uri Guttman

ES> To the OP: If you can live without autovivification, the best answer I
ES> can come up with is to use a factory pattern to build the classes for
ES> you. It's not automatic, but it's nearly so.
ES> A pattern is simply a programming concept. Factory patterns make as
ES> much (or as little, I suppose) sense in Perl as they do in any other
ES> language. Just glancing at the inside of my _Design Patterns_ book,
ES> most of them seem quite applicable to OO programs written in Perl.

and most of them are not needed since perl is so dynamic. calling a
scalar var some silly pattern name just because it can hold ANYTHING
(which requires massive ugly pattern code in c++) is silly. factory
pattern is another silly name. it is so trivial to generate stuff in
perl from multiple classes that even calling it factory is overkill. a
simple hash table of token to class names is all you need. late binding
and polymorphism are built in and do all the hard work.

ES> I agree, more clarification would help here.

which is why your patterns comments seemed even more out of place to me.

uri
 
U

Uri Guttman

ES> A pattern is just a way of thinking about a problem; it's not even an
ES> algorithm. I don't understand your apparent antipathy.

because the concept is oversold and reeks of emperor's new clothes. as i
said perl doens't even need most of the patterns. i program in perl. i
use to do massive amounts in c. i like perl since i don't have to do all
those insane workarounds (AKA patterns) in c to get complex stuff done.

ES> The classic factory pattern implementation would wrap that table with
ES> a function called CreateFoo(); that's hardly overkill. Anyway, you
ES> need some string to index that hash with, and using a factory pattern
ES> doesn't require the user to know the details of how it's generated.

so call it a wrapper. i just don't like the term pattern as approporated
by the GoF. i didn't like the book. period. i felt it was preaching to
the choir and not teaching me anything.

ES> They're helpful, surely, but a Command pattern is useful (especially
ES> when keeping multilevel undo-redo stacks no matter when binding is
ES> done, and polymorphism doesn't remove the need for it. Adapter
ES> patterns are pretty much always going to be required when you have an
ES> existing class whose interface doesn't match that of the environment
ES> you want to use it in.

i may use them but i call them solutions or algorithms or designs but
not patterns. see MJD's take on this at plover.com. i should read the
original pattern language book by alexander which i hear is really about
patterns and not oddly named coding designs.

ES> Because if he's trying to do what I think he's trying to do, then a
ES> factory would help. If he's not, then nevermind. Either way, more
ES> clarification will help.

which is what we both have asked for and not received.

uri
 
D

David Baird

Eric Schwartz said:
Because if he's trying to do what I think he's trying to do, then a
factory would help. If he's not, then nevermind. Either way, more
clarification will help.

-=Eric

Yes, I'm sorry I used the word 'autovivify' - it seemed to fit what
I'm trying to do, but isn't related to autovivification of values in
Perl.

I don't know anything about factories etc, but what I have is a
template of code for a simple package, with a few tokens that I
substitute in. In particular, I substitute in the package name, and an
entry in the @ISA array, to build a hierarchy of classes. So the
template is something like

package <<PACKAGE_NAME>>;
use strict;
use warnings;

use <<PARENT>>;
use vars qw(@ISA);
@ISA = qw(<<PARENT>>);

my %ATTRIBUTES = ( <<ATTRIBUTES>> );

sub attr {
... code to access attributes ...
}

1;

There's also a base class that these classes all inherit from
(directly or indirectly) which supplies a bunch of other methods.

So I got to the stage where I had all the attributes figured out and
substituted into the template, and I wanted to issue a 'use'
statement. I couldn't figure out how to issue that statement though,
because the package only exists in a scalar variable, not as a file on
disk that 'use' would find through its search path. But it seems to
turn out that I can simply eval the string and the package comes into
existence as if I had use'd it. I think. 'use' and 'eval' seem to me
to be very different things, however, so now I'm wondering if there
are any gotchas I need to be aware of.

Is this sort of thing a factory?

FYI, each of these generated classes represents a single table in a
database, and the inheritance between them represents foreign keys. So
all the tables have an 'id' column that relates them to each other.
The attributes hash of each object describes the columns of that
table, and also provides parameters used for generating HTML form
elements for accessing that column through a web page. The base class
provides methods for reading from or writing to the database, and for
generating web forms and validating input.

Thanks,

David.
 
D

David Baird

Uri Guttman said:
which is what we both have asked for and not received.

uri

Well, you're probably in the US, and I'm in the UK, so I was in bed
while you were asking for clarification.

These factories and patterns sound quite fascinating to me. I'm at the
stage of having got quite comfortable with Perl as my first
programming language, and now I'm thinking about learning more
advanced techniques i.e. I have no formal training and I'm wondering
about the theory of programming a bit more. Can you recommend a book
to start with, not necessarily (but preferably) using Perl?

David.
 
E

Eric J. Roode

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

ES> To the OP: If you can live without autovivification, the best
answer I ES> can come up with is to use a factory pattern to build
the classes for ES> you. It's not automatic, but it's nearly so.

ES> A pattern is simply a programming concept. Factory patterns
make as ES> much (or as little, I suppose) sense in Perl as they do
in any other ES> language. Just glancing at the inside of my
_Design Patterns_ book, ES> most of them seem quite applicable to OO
programs written in Perl.

and most of them are not needed since perl is so dynamic. calling a
scalar var some silly pattern name just because it can hold ANYTHING
(which requires massive ugly pattern code in c++) is silly. factory
pattern is another silly name. it is so trivial to generate stuff in
perl from multiple classes that even calling it factory is overkill. a
simple hash table of token to class names is all you need. late
binding and polymorphism are built in and do all the hard work.

Dominus has some insightful (imho) observations on the whole "design
patterns" thing: http://perl.plover.com/yak/design/

- --
Eric
$_ = reverse sort $ /. r , qw p ekca lre uJ reh
ts p , map $ _. $ " , qw e p h tona e and print

-----BEGIN PGP SIGNATURE-----
Version: PGPfreeware 7.0.3 for non-commercial use <http://www.pgp.com>

iQA/AwUBPzywKGPeouIeTNHoEQIBSgCgpC1b3nBcp2xEI6+zppNrgsRYz2gAn310
pQ//OQRo5t6DPBq32EPiz9d6
=0NuT
-----END PGP SIGNATURE-----
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,125
Messages
2,570,748
Members
47,302
Latest member
MitziWragg

Latest Threads

Top