Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Perl classes NOT in separate files

Reply
Thread Tools

Perl classes NOT in separate files

 
 
Andy Glew
Guest
Posts: n/a
 
      12-02-2004
Q: is the below the right way to
place Perl classes "inline", near to where
they are being used?

E.g. in file bar.pl
----------------------------------
use strict
print "Code befre interleaved package/classes\n";
{
package A;
sub new { bless {}; }
sub bar { print "A"; }
}
print "Code between interleaved package/classes\n";
{
package B;
sub new { bless {}; }
sub bar { print "B"; }
}
print "Code after interleaved package/classes\n";
A->bar();
B->bar();
my $a = A->new();
my $b = B->new();
$a->bar();
$b->bar();
----------------------------------

Putting the package statement inside the block curlies
looks wierd, but I guess it's the right way.



I know the basics of Perl classes:
A class is simply a package
A package is simply a file with "packge foo" at the top
(usually one that is on your include path)

Problem: I like to use programming patterns that
create lots of light-weight classes. Typically
they derive from some base class and override
one or two methods as close as possible to the
point of use.

E.g. in C++

int foo() {
class spec1 : public base {
public: int bar() { return 45; }
} s1;
return blif( s1 );

class spec2 : public base {
public: int bar() { return 67; }
} s2;
return blif( s2 );
}

I like this pattern because it puts the
classes right next to the point of use.
(Sometimes language restrictions make you move
them outside a function, but still they are
closer to the point of use than they would be
in a separate function.)

I.e. I use classes almost as a way of creating
lambda functions.

Q: is there any way to do this in Perl?
Placing these classes in separate files
makes them much less lightweight.

I've tried putting package more than once
in a file, with no luck. E.g. how do you
"use" multiple packages from the same file?
Perl seems to tightly couple classes and files.





---
Andy Glew
PREFERRED EMAIL: http://www.velocityreviews.com/forums/(E-Mail Removed)
Although I am trying to quit Outlook,
I fetchmail all of my Outlook/Exchange email
to UNIX to read
FALLBACK EMAIL: (E-Mail Removed)

503-264-4119

Potential bias: employed now by Intel
past by AMD, Intel, Motorola, Gould ...
This post is personal, and is not the opinion of
any of my employers, past or present.
 
Reply With Quote
 
 
 
 
Tom Regner
Guest
Posts: n/a
 
      12-02-2004
Hi Andy,

Andy Glew wrote:

> Q: is the below the right way to
> place Perl classes "inline", near to where
> they are being used?

First guess: remove the curlies and return to a surrounding package (main in
this case):

in file bar.pl
----------------------------------
use strict
print "Code befre interleaved package/classes\n";
package A;
sub new { bless {}; }
sub bar { print "A"; }

package B;
sub new { bless {}; }
sub bar { print "B"; }

package main; # or whatever package is correct here
A->bar();
B->bar();
my $a = A->new();
my $b = B->new();
$a->bar();
$b->bar();
----------------------------------

this compiles and prints

[1117]tom@margo ~ $ perl scratch/scratch.pl
Code befre interleaved package/classes
ABAB

[...]
>
> Q: is there any way to do this in Perl?
> Placing these classes in separate files
> makes them much less lightweight.
>
> I've tried putting package more than once
> in a file, with no luck. E.g. how do you
> "use" multiple packages from the same file?
> Perl seems to tightly couple classes and files.


You don't _use_ them with *use()*, you just *use* them ; I think your
only problem was putting the packages/classes in curlies and not returning
to the main-package (or superclass-package).

BTW, I like this approach for small _lambda_-Classes

hth,
Tom
 
Reply With Quote
 
 
 
 
Anno Siegel
Guest
Posts: n/a
 
      12-02-2004
Andy Glew <(E-Mail Removed)> wrote in comp.lang.perl.misc:
> Q: is the below the right way to
> place Perl classes "inline", near to where
> they are being used?
>
> E.g. in file bar.pl
> ----------------------------------
> use strict
> print "Code befre interleaved package/classes\n";
> {
> package A;
> sub new { bless {}; }
> sub bar { print "A"; }
> }
> print "Code between interleaved package/classes\n";
> {
> package B;
> sub new { bless {}; }
> sub bar { print "B"; }
> }
> print "Code after interleaved package/classes\n";
> A->bar();
> B->bar();
> my $a = A->new();
> my $b = B->new();
> $a->bar();
> $b->bar();
> ----------------------------------
>
> Putting the package statement inside the block curlies
> looks wierd, but I guess it's the right way.


It's fine. If there are run-time actions in the class definition,
you may even want to make the bare block a BEGIN block.

[snip]

> I.e. I use classes almost as a way of creating
> lambda functions.
>
> Q: is there any way to do this in Perl?
> Placing these classes in separate files
> makes them much less lightweight.
>
> I've tried putting package more than once
> in a file, with no luck. E.g. how do you


What's the problem? "No luck" is right there with "doesn't work".
Be specific.

> "use" multiple packages from the same file?
> Perl seems to tightly couple classes and files.


The coupling is between *modules* and file names, and it pertains
only to exportation. Perl decides which ->import method to
(try to) call by looking at the package in the use() statement.
That one corresponds to the file name.

For non-exporting packages, as are classes, the difference is
irrelevant. You can have as many of them in a file as you want.

Anno
 
Reply With Quote
 
Tom Regner
Guest
Posts: n/a
 
      12-02-2004

reading Anno Siegels Post (<comrpg$a5f$(E-Mail Removed)-Berlin.DE>), I
realized that the original code already worked as expected, I just assumed
a problem -- silly me.

So I wish I could 'unwrite' most of my original answer


Tom Regner wrote:
[lots of silly things]
> You don't _use_ them with *use()*, you just *use* them ;

[...]
>
> BTW, I like this approach for small _lambda_-Classes
>
> hth,
> Tom



kind regards,
Tom
 
Reply With Quote
 
Andy Glew
Guest
Posts: n/a
 
      12-03-2004
> > [Me, Andy Glew --- (E-Mail Removed)]
> > print "Code befre interleaved package/classes\n";
> > {
> > package A;
> > sub new { bless {}; }
> > sub bar { print "A"; }
> > }
> > print "Code between interleaved package/classes\n";
> > {
> > package B;
> > sub new { bless {}; }
> > sub bar { print "B"; }
> > }


> > I've tried putting package more than once
> > in a file, with no luck. E.g. how do you

>

http://www.velocityreviews.com/forums/(E-Mail Removed)-berlin.de (Anno Siegel) writes:
> What's the problem? "No luck" is right there with "doesn't work".



Sorry. The last time I tried this (multiple packages per file) was
many years ago (circa 1996-2000) on a much earlier version of Perl. I
only vaguely remember that, but I think I did

package A;
...
package B;
...

instead of

{
package A;
...
}
{
package B;
...
}

Whatever I did back then, I could not get it to work.


I realized, as I was writing the post, that embedding the package in
curly braces works. It may even work without the curly braces,
but I prefer the curly block because it allows me to embed
the package right in the code - see below.

I thought that I had fixed my post to reflect this --- to now just be
a question "Is this the best way to do multiple packages in the same
file?" But apparently I did not catch everything. Sorry.


So, is this the best way to embed packages in a file?

{
package A;
...
}
{
package B;
...
}

By the way, I like using the curly block because it allows me to place
a package in the middle of code. To my surprise

sub bar {
my $arg = shift;

package foo {
...
}

...
}

seems to work.

---

Follow-on question: what about nested packages
within the same file? Or, nested packages period.

{
package A;
...
{
package B;
...
}
}

did *NOT* do what I, well, didn't really expect
but might have hoped for.

Even though nested like this, package B is defined
in the global scope. I had been hoping that it
might be defined as A::B, i.e. nested.

I was hoping that I could use this so that
I did not have to worry as much about namespace collisions.

E.g.
{
package A;
{
package helper;
sub hello { print "A...helper\n";}
}
}
helper::hello();
{
package B;
{
package helper;
sub hello { print "B...helper\n";}
}
}
helper::hello();

Produces
B...helper
B...helper


I.e. A's helper is defined over. That is unfortunate.


--
---
Andy Glew

Potential bias: employed now by Intel
past by AMD, Intel, Motorola, Gould ...
This post is personal, and is not the opinion of
any of my employers, past or present.
 
Reply With Quote
 
Ben Morrow
Guest
Posts: n/a
 
      12-03-2004

Quoth Andy Glew <(E-Mail Removed)>:
> > > [Me, Andy Glew --- (E-Mail Removed)]
> > > print "Code befre interleaved package/classes\n";
> > > {
> > > package A;
> > > sub new { bless {}; }
> > > sub bar { print "A"; }
> > > }
> > > print "Code between interleaved package/classes\n";
> > > {
> > > package B;
> > > sub new { bless {}; }
> > > sub bar { print "B"; }
> > > }

>
> > > I've tried putting package more than once
> > > in a file, with no luck. E.g. how do you

> >

> (E-Mail Removed)-berlin.de (Anno Siegel) writes:
> > What's the problem? "No luck" is right there with "doesn't work".

>
>
> Sorry. The last time I tried this (multiple packages per file) was
> many years ago (circa 1996-2000) on a much earlier version of Perl. I
> only vaguely remember that, but I think I did
>
> package A;
> ...
> package B;
> ...


This will work correctly.

<snip>
> So, is this the best way to embed packages in a file?
>
> {
> package A;
> ...
> }
> {
> package B;
> ...
> }


It's certainly what I would do, modulo making those blocks BEGIN blocks
if necessary. (Actually, following a post of (IIRC) Anno's a while back,
I'd format it like

{{

package A;

....;

}}

{{

package B;

}}

just to stop the nesting getting too deep.)

> By the way, I like using the curly block because it allows me to place
> a package in the middle of code. To my surprise
>
> sub bar {
> my $arg = shift;
>
> package foo {
> ...
> }
>
> ...
> }
>
> seems to work.


No it doesn't.

~% perl -le'package foo { 1; }'
syntax error at -e line 1, near "package foo { "
Execution of -e aborted due to compilation errors.

> Follow-on question: what about nested packages
> within the same file? Or, nested packages period.
>
> {
> package A;
> ...
> {
> package B;
> ...
> }
> }
>
> did *NOT* do what I, well, didn't really expect
> but might have hoped for.
>
> Even though nested like this, package B is defined
> in the global scope. I had been hoping that it
> might be defined as A::B, i.e. nested.


Yes. A package statement is lexically scoped, but the packages
themselves are global. Note that the package A::B is in no sense (at the
Perl level, anyway) inside package A. It is just a package that happens
to have a :: in the middle of it's name.

> I was hoping that I could use this so that
> I did not have to worry as much about namespace collisions.
>
> E.g.
> {
> package A;
> {
> package helper;
> sub hello { print "A...helper\n";}
> }
> }
> helper::hello();


If this has done what you expect this statement would have produced an
'undefined subroutine' error. It would have needed to be inside the
block.

> {
> package B;
> {
> package helper;
> sub hello { print "B...helper\n";}
> }
> }
> helper::hello();
>
> Produces
> B...helper
> B...helper
>
> I.e. A's helper is defined over. That is unfortunate.


I agree it's unfortunate. It is doubly unfortunate that there appears to
be no workaround (at least, not without using XS; with XS it's trivial,
so there may even be a module on CPAN to do it).

Note also that all top-level packages beginning with a lower-case letter
are reserved for future pragmas, so you shouldn't use them.

Ben

--
Every twenty-four hours about 34k children die from the effects of poverty.
Meanwhile, the latest estimate is that 2800 people died on 9/11, so it's like
that image, that ghastly, grey-billowing, double-barrelled fall, repeated
twelve times every day. Full of children. [Iain Banks] (E-Mail Removed)
 
Reply With Quote
 
Brian McCauley
Guest
Posts: n/a
 
      12-04-2004


Andy Glew wrote:

>>>[Me, Andy Glew --- (E-Mail Removed)]
>>>print "Code befre interleaved package/classes\n";
>>>{
>>> package A;
>>> sub new { bless {}; }
>>> sub bar { print "A"; }
>>>}
>>>print "Code between interleaved package/classes\n";
>>>{
>>> package B;
>>> sub new { bless {}; }
>>> sub bar { print "B"; }
>>>}

>
>
>>>I've tried putting package more than once
>>>in a file, with no luck. E.g. how do you

>>

> (E-Mail Removed)-berlin.de (Anno Siegel) writes:
>
>>What's the problem? "No luck" is right there with "doesn't work".

>
>
>
> Sorry. The last time I tried this (multiple packages per file) was
> many years ago (circa 1996-2000) on a much earlier version of Perl. I
> only vaguely remember that, but I think I did
>
> package A;
> ...
> package B;
> ...
>
> instead of
>
> {
> package A;
> ...
> }
> {
> package B;
> ...
> }
>
> Whatever I did back then, I could not get it to work.
>
>
> I realized, as I was writing the post, that embedding the package in
> curly braces works. It may even work without the curly braces,
> but I prefer the curly block because it allows me to embed
> the package right in the code - see below.


What you mean is you don't need to explicitly set the package back to
main. Both will of course work.

> So, is this the best way to embed packages in a file?


I don't think either is universally better.

> To my surprise


> package foo {
> ...
> }


> seems to work.


No it does not.

> Follow-on question: what about nested packages
> within the same file? Or, nested packages period.
>
> {
> package A;
> ...
> {
> package B;
> ...
> }
> }
>
> did *NOT* do what I, well, didn't really expect
> but might have hoped for.
>
> Even though nested like this, package B is defined
> in the global scope. I had been hoping that it
> might be defined as A::B, i.e. nested.


No all package names in Perl are absolute

> I was hoping that I could use this so that
> I did not have to worry as much about namespace collisions.


Yes, I've often wished there was a simple way to specify relative
package names in Perl.

 
Reply With Quote
 
Andy Glew
Guest
Posts: n/a
 
      12-09-2004
> > To my surprise
>
> > package foo {
> > ...
> > }

>
> > seems to work.

>
> No it does not.


Sorry again, I'm full of typos.

To my surprise

sub bar {
...
{
package foo;
....
}
}

seems to work, although names in foo
are defined absolutely.


---

But I'm probably wrong, and really should post
an experiment. Won't bother, because it
was the nesting I most wanted.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Separate Tabs, Separate Sessions BigAndy Firefox 0 05-09-2007 09:27 AM
Separate Tabs, Separate Sessions BigAndy Firefox 0 05-09-2007 09:26 AM
Using separate classpaths for separate classes? Frank Fredstone Java 1 06-27-2006 06:46 AM
getting access to classes in separate vb files Humberto Alvarez ASP .Net 4 01-04-2006 08:04 PM
How to use several separate classes (separate files) to be executed in one class (another file) EvgueniB Java 1 12-15-2003 01:18 AM



Advertisments