Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

A Perl 6 class question

5 views
Skip to first unread message

Chris Dutton

unread,
Aug 9, 2002, 3:09:29 PM8/9/02
to perl6-l...@perl.org
Since Adam Lopesto asked a non-regex question, I don't feel quite as out
of place for doing the same.

This one actually came to me just the other night. Would it be possible
in Perl 6 to create "anonymous classes"? Something like:

my $foo_class = class {
method new {
# yada yada yada
}
}

my $foo_obj = $foo_class.new;

Piers Cawley

unread,
Aug 10, 2002, 6:25:25 PM8/10/02
to Chris Dutton, perl6-l...@perl.org
Chris Dutton <ch...@cmb-enterprises.com> writes:

I hope so.

--
Piers

"It is a truth universally acknowledged that a language in
possession of a rich syntax must be in need of a rewrite."
-- Jane Austen?

Chris Dutton

unread,
Aug 10, 2002, 7:30:19 PM8/10/02
to perl6-l...@perl.org
On Saturday, August 10, 2002, at 06:25 PM, Piers Cawley wrote:

> Chris Dutton <ch...@cmb-enterprises.com> writes:
>
>> Since Adam Lopesto asked a non-regex question, I don't feel quite as
>> out of place for doing the same.
>>
>> This one actually came to me just the other night. Would it be
>> possible in Perl 6 to create "anonymous classes"? Something like:
>>
>> my $foo_class = class {
>> method new {
>> # yada yada yada
>> }
>> }
>>
>> my $foo_obj = $foo_class.new;
>
> I hope so.

The only problem I could see, and I wanted to wait for at least one
other opinion before mentioning this, is rewriting the above as:

my $foo_class $foo_obj = $foo_class.new;

Still I can see this as occasionally being useful for having instance
variables which can effectively be initialized, but afterwards are
constant. Then again, there's probably another, more graceful way to do
this using the new method and properties.

sub foo(int $bar //= 0) {
return class {
int $.baz is constant = $bar;
method out(int $multiply_by //= 1) {
print $.baz * $multiply_by, "\n";
}
}
}

foo(5).new.out(2); # 10
foo(6).new.out(3); # 18

Allison Randal

unread,
Aug 12, 2002, 11:44:23 AM8/12/02
to Chris Dutton, perl6-l...@perl.org
On Fri, Aug 09, 2002 at 03:09:29PM -0400, Chris Dutton wrote:
>
> This one actually came to me just the other night. Would it be possible
> in Perl 6 to create "anonymous classes"? Something like:
>
> my $foo_class = class {
> method new {
> # yada yada yada
> }
> }
>
> my $foo_obj = $foo_class.new;

Yup. Reread the section of Exegesis 4 on "Lexical Exceptions". You even
got the exact syntax (always a nice confirmation of how natural it is :).

Allison

Trey Harris

unread,
Aug 12, 2002, 11:56:48 AM8/12/02
to Allison Randal, perl6-l...@perl.org
Another one...

class Foo is Bar;

method a {
setup();
}

1;
# EOF

(Is the 1 still required? I think I heard Damian say it was going away.)

The question is, is this valid, if Bar defines a sub/static method
'setup'?

Is my instict right that 'sub' in a class is a 'class/static method' in
the terminology of other languages?

I'm wondering if the oddly redundant syntax we have now of:

package Foo;
use Bar;
our @ISA = qw(Bar);
sub a {
my $self = shift;
Bar::setup();
}
1;

Can go away.

Trey

Allison Randal

unread,
Aug 12, 2002, 1:27:15 PM8/12/02
to Chris Dutton, perl6-l...@perl.org
On Sat, Aug 10, 2002 at 07:30:19PM -0400, Chris Dutton wrote:
>
> The only problem I could see, and I wanted to wait for at least one
> other opinion before mentioning this, is rewriting the above as:
>
> my $foo_class $foo_obj = $foo_class.new;

I'm not exactly sure what you're trying to do with this. You can create
an object within the same statement as you define the class:

my $foo_obj = class {


method new {
# yada yada yada
}

}.new;

> Still I can see this as occasionally being useful for having instance
> variables which can effectively be initialized, but afterwards are
> constant. Then again, there's probably another, more graceful way to do
> this using the new method and properties.
>
> sub foo(int $bar //= 0) {
> return class {
> int $.baz is constant = $bar;
> method out(int $multiply_by //= 1) {
> print $.baz * $multiply_by, "\n";
> }
> }
> }
>
> foo(5).new.out(2); # 10
> foo(6).new.out(3); # 18

As it stands, you're not gaining anything over:

sub foo(int $bar //= 0, int $multiply_by //= 1) {
print $bar * $multiply_by, "\n";
}

foo(5,2);

I'll tease out the various threads there. Keep in mind that the new OO
syntax is only partially defined at this point. Yes, you will be able to
return an anonymous class. Yes, it will be lexically scoped to the
context in which it was defined, so it will have access to $bar. Yes,
attributes can have properties attached, and I imagine C<is constant>
will be one of the acceptable properties. I also imagine attributes will
have the option of being initialized using assignment-style (C<=>)
syntax. I also imagine that attributes will be able to be typed. The
current consensus on attribute declaration is to use this syntax:

attr $.baz;

(i.e. C<attr>, not C<my> or C<our>)
Or in your case:

attr int $.baz is constant = $bar;

> foo(5).new.out(2); # 10

I suspect this will be allowable syntax. But if you find yourself using
it you might want to re-think the code. Creating a class and an object
for single use isn't tremendously efficient. Then again, you may be
golfing. :)

Allison

Chris Dutton

unread,
Aug 12, 2002, 3:10:43 PM8/12/02
to Allison Randal, perl6-l...@perl.org
On Monday, August 12, 2002, at 01:27 PM, Allison Randal wrote:

> On Sat, Aug 10, 2002 at 07:30:19PM -0400, Chris Dutton wrote:
>>
>> The only problem I could see, and I wanted to wait for at least one
>> other opinion before mentioning this, is rewriting the above as:
>>
>> my $foo_class $foo_obj = $foo_class.new;
>
> I'm not exactly sure what you're trying to do with this.

Sort of like:

class A { ... }
my A $a = A.new;

Where A is $foo_class. Probably not terribly useful, but I just
wondered if it'd work anyway.

> You can create
> an object within the same statement as you define the class:
>
> my $foo_obj = class {
> method new {
> # yada yada yada
> }
> }.new;

I figured that would work, but wasn't entirely sure. Thanks.

>> sub foo(int $bar //= 0) {
>> return class {
>> int $.baz is constant = $bar;
>> method out(int $multiply_by //= 1) {
>> print $.baz * $multiply_by, "\n";
>> }
>> }
>> }
>>
>> foo(5).new.out(2); # 10
>> foo(6).new.out(3); # 18
>
> As it stands, you're not gaining anything over:
>
> sub foo(int $bar //= 0, int $multiply_by //= 1) {
> print $bar * $multiply_by, "\n";
> }
>
> foo(5,2);

Granted, it was a trivial example. :-)

> attr int $.baz is constant = $bar;

I like it.

>> foo(5).new.out(2); # 10
>
> I suspect this will be allowable syntax. But if you find yourself using
> it you might want to re-think the code. Creating a class and an object
> for single use isn't tremendously efficient. Then again, you may be
> golfing. :)

Hmmm.... could I have instead written the following and ended up with
both a lexically scoped anonymous class($fc), and an instance($fo)?

( my $fo = ( my $fc = foo(5) ).new ).out;

One thing is obvious... it's been way too long since I read the various
Exegesis documents.

Damian Conway

unread,
Aug 16, 2002, 8:08:36 PM8/16/02
to perl6-l...@perl.org
Trey Harris asked:

> Another one...
>
> class Foo is Bar;
>
> method a {
> setup();
> }
>
> 1;
> # EOF
>
> (Is the 1 still required?

No.


> I think I heard Damian say it was going away.)

Yes.


> The question is, is this valid, if Bar defines a sub/static method
> 'setup'?

If C<setup> is a C<sub>, yes.
But if it is a C<method>, you'd need:

method a {
.setup();
}


> Is my instict right that 'sub' in a class is a 'class/static method' in
> the terminology of other languages?

Not really. C<sub> denotes a helper subroutine.
Methods should always declared with the declarator C<method>.


> I'm wondering if the oddly redundant syntax we have now of:
>
> package Foo;
> use Bar;
> our @ISA = qw(Bar);
> sub a {
> my $self = shift;
> Bar::setup();
> }
> 1;
>
> Can go away.

Yep. In Perl 6 that would be:

class Foo is Bar {
method a {

Bar::setup();
}
}

or, if C<Bar::setup> is a *method*, rather than a subroutine:

class Foo is Bar {
method a ($self:) {
$self.setup();
}
}

or, because the invocant is implicitly the topic in a method, just:

class Foo is Bar {
method a {

.setup();
}
}


Damian


0 new messages