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

globs?

7 views
Skip to first unread message

Paul

unread,
Apr 8, 2003, 4:56:03 PM4/8/03
to perl6-l...@perl.org

Ok, here's what's been itching my brain.

P5:
===
# bad code used for example:
# version 1
# $obj->foo(\@attrs,@vals);
sub foo {
my $self = shift;
local *bar = $self; # object is hashref
my $lstref = shift;
@bar{ @{$lstref} } = @_; # <<== here's the rub
}

# version 2
# $obj->foo(%newstuff);
sub foo {
my $self = shift;
local *bar = $self; # object is hashref
my %newstf = @_;
@bar{ keys %newstf } = values %newstf; # <<== here
}

This is obviously ugly code, but I've used stuff like it to bulk set
specific properties on an object without overwriting others.
I realize that such hacks probably won't be *needed* much in P6....
But what really confuses me is.... where did globs go?

Have I completely misread what's being rolled around?
Or missed some apocolyptic pronouncement? Or is it gonna be A8?

Ref's are pretty clean, while globs have been a little more like
pointers... use with caveats, only when needed... but I *like* globs
(and pointers, too, for that matter).

I'm sure that with P6, self-dereferencing may just absorb that sort of
problem, so that a bulk assignment to object properties becomes simpler
and more efficient and more readable and a slew of other better-nesses,
but I just don't have enough P6 under my belt to envision how I'd
reimplement some of these things.

I know the above could have been done in a loop:

# $obj->foo(%newstuff);
sub foo {
my $self = shift;
my %newstf = @_;
$self->{$_} = $newstf{$_} for keys %newstf;
}

I even admit that it might be more readable/maintainable. I suspect it
might be slower, but don't pretend to understand such optimizations
well enough to really know without benchmarking it, which I haven't
done recently. I'm just hoping to learn by some examples.

Generally, this is my take on it....

P6:
===
# version 1
# $obj->foo(@attrs,@vals);
my method foo (%me: @a, @b ) {
%me{ @a } = @b;
}

I suspect I've screwed up several things in even so short an example,
but if that's anywhere close, it at least explains why globs went away.
:)

# version 2
# $obj->foo(%newstuff);
my method foo (%me: %n ) {
%me{ %n.keys } = %n.values;
}

To me, this is where we want to go. That's still Perl, but @#$%^&!!!
Look at the improvement! No requirement for all the sloppy
localization, it's READABLE, and *very* straightforward. Admittedly,
the old code was *bad* code, but this is so much easier and cleaner
that it would take real work to write code even half as bad. (Of
course, I'm pretty talented there.... ;)

So, as I suspected, "talking it out" is making it make more sense, and
I suspect that people will come back with comments and corrections that
will clarify a lot for me, too. So please, feel free to poke -- that's
why I'm posting. >:O)

Paul

__________________________________________________
Do you Yahoo!?
Yahoo! Tax Center - File online, calculators, forms, and more
http://tax.yahoo.com

Graham Barr

unread,
Apr 8, 2003, 5:01:12 PM4/8/03
to Hod...@writeme.com, perl6-l...@perl.org
On Tue, Apr 08, 2003 at 01:56:03PM -0700, Paul wrote:
>
> Ok, here's what's been itching my brain.
>
> P5:
> ===
> # bad code used for example:
> # version 1
> # $obj->foo(\@attrs,@vals);
> sub foo {
> my $self = shift;
> local *bar = $self; # object is hashref
> my $lstref = shift;
> @bar{ @{$lstref} } = @_; # <<== here's the rub
> }

> I know the above could have been done in a loop:


>
> # $obj->foo(%newstuff);
> sub foo {
> my $self = shift;
> my %newstf = @_;
> $self->{$_} = $newstf{$_} for keys %newstf;
> }

It could also be done with

sub foo {
my $self = shift;

my $lstref = shift;
@{$self}{ @{$lstref} } = @_;
}

No need for the glob.

Graham.

Uri Guttman

unread,
Apr 8, 2003, 5:14:10 PM4/8/03
to Hod...@writeme.com, perl6-l...@perl.org
>>>>> "P" == Paul <ydb...@yahoo.com> writes:

P> sub foo {
P> my $self = shift;
P> local *bar = $self; # object is hashref
my $bar = shift ;

P> my $lstref = shift;
P> @bar{ @{$lstref} } = @_; # <<== here's the rub

@{$bar}{ @{$lstref} } = @_;

P> }

P> # version 2
P> # $obj->foo(%newstuff);
P> sub foo {
P> my $self = shift;
P> local *bar = $self; # object is hashref

kill that line

P> my %newstf = @_;
P> @bar{ keys %newstf } = values %newstf; # <<== here

@{$bar}{ keys %newstf } = values %newstf;

P> }

P> This is obviously ugly code, but I've used stuff like it to bulk set
P> specific properties on an object without overwriting others.
P> I realize that such hacks probably won't be *needed* much in P6....
P> But what really confuses me is.... where did globs go?

well, as you can see they weren't needed in the above code so larry and
damian exorcised them from the now pure body of perl 6.

P> Ref's are pretty clean, while globs have been a little more like
P> pointers... use with caveats, only when needed... but I *like* globs
P> (and pointers, too, for that matter).

globs were not needed once real refs were created. you could always use
symrefs to mung the symbol table. in p6 access to the symbol table will
be direct and clean so globs aren't needed for that. and handles (file,
dir and ??) will be objects created by open* (prolly returned and not
passed in like in p5).

P> I know the above could have been done in a loop:

as i showed, slices work fine with hard refs.

uri

--
Uri Guttman ------ u...@stemsystems.com -------- http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org

Paul

unread,
Apr 8, 2003, 5:20:39 PM4/8/03
to Graham Barr, perl6-l...@perl.org

--- Graham Barr <gb...@pobox.com> wrote:
> On Tue, Apr 08, 2003 at 01:56:03PM -0700, Paul wrote:
> > # $obj->foo(\@attrs,@vals);
> > sub foo {
> > my $self = shift;
> > local *bar = $self; # object is hashref
> > my $lstref = shift;
> > @bar{ @{$lstref} } = @_; # <<== here's the rub
> > }
>
> It could also be done with
>
> sub foo {
> my $self = shift;
> my $lstref = shift;
> @{$self}{ @{$lstref} } = @_;
> }
>
> No need for the glob.

But even so, which is faster? That's a lot of dynamic dereferencing....

Not that either is going to be terribly quick.

Worst of all, it's blessedly unreadable. @{$self} would give me
headaches in a couple of months when I came back to read it, because I
know that's a *hash* ref.... "oh yeah, those curlies after it make it a
hash" would take me a bit, expecially with all the line noise of
{ @{$lstref} } (a reaf array deref) beside it.

I think I opted for the local() alias just to minimize the maintenance
confusion, though it's a horrible solution in either case to me.

*Man* I'm gonna be happy when P6 gets here! :)

Either way, thanks Graham.

Matthijs Van Duin

unread,
Apr 8, 2003, 5:24:08 PM4/8/03
to perl6-l...@perl.org
On Tue, Apr 08, 2003 at 02:20:39PM -0700, Paul wrote:
>> sub foo {
>> my $self = shift;
>> my $lstref = shift;
>> @{$self}{ @{$lstref} } = @_;
>> }
>
>Worst of all, it's blessedly unreadable. @{$self} would give me
>headaches in a couple of months when I came back to read it, because I
>know that's a *hash* ref.... "oh yeah, those curlies after it make it a
>hash" would take me a bit, expecially with all the line noise of
>{ @{$lstref} } (a reaf array deref) beside it.

So write:

@$self{@$lstref} = @_;

--
Matthijs van Duin -- May the Forth be with you!

Luke Palmer

unread,
Apr 8, 2003, 5:28:34 PM4/8/03
to Hod...@writeme.com, perl6-l...@perl.org

Others have answered the other part of this sufficiently, so I've
snipped it.

> Generally, this is my take on it....
>
> P6:
> ===
> # version 1
> # $obj->foo(@attrs,@vals);
> my method foo (%me: @a, @b ) {
> %me{ @a } = @b;
> }
>
> I suspect I've screwed up several things in even so short an example,
> but if that's anywhere close, it at least explains why globs went away.
> :)

Yep. First, Objects aren't hashrefs underneath anymore. (Well, they
might be, but not at the language level (well, probably not. There's
no way to know until A12)).

> # version 2
> # $obj->foo(%newstuff);
> my method foo (%me: %n ) {
> %me{ %n.keys } = %n.values;
> }

No. But, for these kinds of cases (where attributes are set in a
constructor, at least), we have:

submethod BUILD($me: +$.a, +$.b) { }

Which does that for two named parameters a and b. I assume this can
be generalized to:

submethod BUILD($me: *%.slurp) { }

Which would set all attributes given in that command line. And
hopefully it would err if an option was given that wasn't a real
attribute.

And, for *similar* cases, I assume there will be some concise
equivalent to version 2. Like:

my method foo($me: *%slurp) {
%.HAS{%slurp.keys} = %slurp.values;
}

> To me, this is where we want to go. That's still Perl, but @#$%^&!!!
> Look at the improvement! No requirement for all the sloppy
> localization, it's READABLE, and *very* straightforward. Admittedly,
> the old code was *bad* code, but this is so much easier and cleaner
> that it would take real work to write code even half as bad. (Of
> course, I'm pretty talented there.... ;)
>
> So, as I suspected, "talking it out" is making it make more sense, and
> I suspect that people will come back with comments and corrections that
> will clarify a lot for me, too. So please, feel free to poke -- that's
> why I'm posting. >:O)

The main reason I use typeglobs is for symbol table manipulation. And
I find that even then, using the %Package:: hashes is cleaner. If
you're going to screw with the symbol table, use the *symbol table*.

But as far as the readablity thing, and the straightforward thing,
that is Perl 6. It's expresiveness is far greater than any language
I've seen, or could think of myself. That's why I continue to put my
time and energy into the project.

Luke

Paul

unread,
Apr 8, 2003, 5:28:55 PM4/8/03
to Uri Guttman, perl6-l...@perl.org

--- Uri Guttman <u...@stemsystems.com> wrote:
> >>>>> "P" == Paul <ydb...@yahoo.com> writes:
> P> sub foo {
> P> my $self = shift;
> P> local *bar = $self; # object is hashref
> my $bar = shift ;

shift?
I think you meant to use the same solution as Graham suggested.
Just take out *bar entirely and use $self.

> P> my $lstref = shift;
> P> @bar{ @{$lstref} } = @_; # <<== here's the rub
> @{$bar}{ @{$lstref} } = @_;
> P> }

Yeah, @{$self}{ @{$lstref} } works fine.
It's just horribly ugly -- possibly even worse than the alias.



> P> # version 2
> P> # $obj->foo(%newstuff);
> P> sub foo {
> P> my $self = shift;
> P> local *bar = $self; # object is hashref
>
> kill that line
>
> P> my %newstf = @_;
> P> @bar{ keys %newstf } = values %newstf; # <<== here
>
> @{$bar}{ keys %newstf } = values %newstf;

@{$self}{ keys %newstf } = values %newstf;

I understand that.



> P> }
>
> P> This is obviously ugly code, but I've used stuff like it to bulk
> set
> P> specific properties on an object without overwriting others.
> P> I realize that such hacks probably won't be *needed* much in
> P6....
> P> But what really confuses me is.... where did globs go?
>
> well, as you can see they weren't needed in the above code so larry
> and damian exorcised them from the now pure body of perl 6.

And a good thing, too.

> P> Ref's are pretty clean, while globs have been a little more like
> P> pointers... use with caveats, only when needed... but I *like*
> globs
> P> (and pointers, too, for that matter).
>
> globs were not needed once real refs were created. you could always
> use symrefs to mung the symbol table. in p6 access to the symbol
> table will be direct and clean so globs aren't needed for that. and
> handles (file, dir and ??) will be objects created by open* (prolly
> returned and not passed in like in p5).

As in
my $fh = open ">foo" or die $!; # ?

That's cool.

> P> I know the above could have been done in a loop:
> as i showed, slices work fine with hard refs.
> uri

I knew that. It wasn't that I didn't know how to do it in P5 (though it
probably looked that way, lol....)

I was just trying to figure out how to do it in P6, and sort of
"thinking out loud".

Wierd -- I expected replies showing me how to correct my P6 versions.
Nobody's done that yet, lol.... just the P5. I *know* that was bad, and
said so. The point was that I was using code that used a glob as an
example.

Funny. :)

Paul

unread,
Apr 8, 2003, 5:39:15 PM4/8/03
to Matthijs van Duin, perl6-l...@perl.org

lol -- ok, I obviously babbled.
This is betterin some ways, but not the point. :)
I was intentionally using a glob.
(Even so, there is some argument *for* the line noise when deref'ing
something this complex....but that's not really an issue for P6
language.)

Even so, with a reasonably readable

sub foo {
my $self = shift;
my $lstref = shift;

@$self{ @$lstref } = @_;
}

I think P6's

my method foo ( %me: @a, @b ) {
%me{ @a } = @b;
}

is MUCH better in a hundred ways.
I just figured I probably was missing something.

My general "question", of which there wasn't really one, was "am I
getting this".

Sorry if it was just spamming the list -- it was just too quiet, and I
thought thinking it through in writing might spur some new epiphany. It
did for me, anyway.

Luke Palmer

unread,
Apr 8, 2003, 5:43:19 PM4/8/03
to Hod...@writeme.com, u...@stemsystems.com, perl6-l...@perl.org
> Wierd -- I expected replies showing me how to correct my P6 versions.
> Nobody's done that yet, lol.... just the P5. I *know* that was bad, and
> said so. The point was that I was using code that used a glob as an
> example.
>
> Funny. :)

Probably because everybody here knows P5 better than anybody knows P6.
I mean, uh:

all(map { .p5_knowledge } %people) > any(map { .p6_knowledge } %people)

Junctions are so cool! :)

Luke

Uri Guttman

unread,
Apr 8, 2003, 5:49:50 PM4/8/03
to Luke Palmer, Hod...@writeme.com, perl6-l...@perl.org
>>>>> "LP" == Luke Palmer <fibo...@babylonia.flatirons.org> writes:

LP> Probably because everybody here knows P5 better than anybody knows P6.
LP> I mean, uh:

LP> all(map { .p5_knowledge } %people) > any(map { .p6_knowledge } %people)

LP> Junctions are so cool! :)

where does damian fit into that junction? i am not sure if it is true
because of him. :)

Paul

unread,
Apr 8, 2003, 5:56:43 PM4/8/03
to Luke Palmer, perl6-l...@perl.org

--- Luke Palmer <fibo...@babylonia.flatirons.org> wrote:
> Others have answered the other part of this sufficiently, so I've
> snipped it.

lol -- bless ya. ;o]

> > my method foo (%me: @a, @b ) { %me{ @a } = @b; }
> > I suspect I've screwed up several things in even so short an
> > example, but if that's anywhere close, it at least explains why
> > globs went away.
>

> Yep. First, Objects aren't hashrefs underneath anymore. (Well, they
> might be, but not at the language level (well, probably not. There's
> no way to know until A12)).

Well, object weren't *always* hashrefs in P5. They were just refs of
some sort, and hashes are darned convenient. :)
But does that mean it would *have* to be

my method foo ($me: @a, @b ) { # . . . . ?

I can live with that; just trying to learn it!

> > my method foo (%me: %n ) { %me{ %n.keys } = %n.values; }
>
> No. But, for these kinds of cases (where attributes are set in a
> constructor, at least), we have:
>
> submethod BUILD($me: +$.a, +$.b) { }
>
> Which does that for two named parameters a and b. I assume this can
> be generalized to:
>
> submethod BUILD($me: *%.slurp) { }
>
> Which would set all attributes given in that command line. And
> hopefully it would err if an option was given that wasn't a real
> attribute.
>
> And, for *similar* cases, I assume there will be some concise
> equivalent to version 2. Like:
>
> my method foo($me: *%slurp) {
> %.HAS{%slurp.keys} = %slurp.values;
> }

Ok -- %.HAS ???
That looks vaguely familiar, and makes good sense, but twists the brain
a bit. I read that as representing a hash property on the current
object named HAS, which is in all caps so is probably standard. It
rings little bells, but I obviously need more research. Got a reference
so I can RTFM in the appropriate location? :)

And %slurp is the name of a slurpy hash parameter as declared by the
flattening *%slurp; that's simple enough, though it took me a half-sec
to realize "slurp" wasn't being used as some sort of keyword there,
lol....



> The main reason I use typeglobs is for symbol table manipulation.
> And I find that even then, using the %Package:: hashes is cleaner.
> If you're going to screw with the symbol table, use the *symbol
> table*.

Makes sense. :)
You know,sometimes there's nothing more painful than going back to old
code that works, and that you *know* you don't have time to rewrite,
but that literally hurts you to look at because of the *bad* things you
did before you knew better, lol.... I got this trash example out of one
of the first old modules I wrote when I was trying to learn OO.... >:O}



> But as far as the readablity thing, and the straightforward thing,
> that is Perl 6. It's expresiveness is far greater than any language
> I've seen, or could think of myself. That's why I continue to put my
> time and energy into the project.
> Luke

And why yesterday I *finally* got around to contributing to YAS/TPF.
Thanks again, btw. ;o]

Paul

Larry Wall

unread,
Apr 8, 2003, 6:55:43 PM4/8/03
to perl6-l...@perl.org
On Tue, Apr 08, 2003 at 02:39:15PM -0700, Paul wrote:
: I think P6's

:
: my method foo ( %me: @a, @b ) {
: %me{ @a } = @b;
: }
:
: is MUCH better in a hundred ways.

Except, of course, that that's not P6. :-/

In P6, the object is opaque, and may only be bound to a scalar
variable. If you want a class to have a hash, the object isn't a
blessed hash--it merely *contains* the hash as an attribute:

class MyClass {
has %.me;
method foo (@a, @b) {
%.me{ @a } = @b;
}
}

Note that you don't have to mention the invocant at all.

Larry

Austin Hastings

unread,
Apr 8, 2003, 7:18:09 PM4/8/03
to Larry Wall, perl6-l...@perl.org

Larry, for the fourth time it has occured to me that saying:

class MyClass {
has $.attr;
}

implies being able to say:

class MyClass {
has $attr; # no "dot"
}

What do you do when that happens? (Is that the way to do class vars?)

=Austin

Paul

unread,
Apr 9, 2003, 10:04:30 AM4/9/03
to Larry Wall, perl6-l...@perl.org

--- Larry Wall <la...@wall.org> wrote:
> On Tue, Apr 08, 2003 at 02:39:15PM -0700, Paul wrote:
> : I think P6's
> :
> : my method foo ( %me: @a, @b ) {
> : %me{ @a } = @b;
> : }
> :
> : is MUCH better in a hundred ways.
>
> Except, of course, that that's not P6. :-/

No surprise. :)
That was, after all, one of the main reasons I posted it!
And the example I was hoping for follows, with suitable exposition:



> In P6, the object is opaque, and may only be bound to a scalar
> variable. If you want a class to have a hash, the object isn't a
> blessed hash--it merely *contains* the hash as an attribute:
>
> class MyClass {
> has %.me;
> method foo (@a, @b) {
> %.me{ @a } = @b;
> }
> }
>
> Note that you don't have to mention the invocant at all.
> Larry

Beautiful, and thanks.
And even better, and again, thanks, lol....

Larry Wall

unread,
Apr 9, 2003, 1:07:34 PM4/9/03
to perl6-l...@perl.org
On Tue, Apr 08, 2003 at 06:18:09PM -0500, Austin Hastings wrote:
: Larry, for the fourth time it has occured to me that saying:

:
: class MyClass {
: has $.attr;
: }
:
: implies being able to say:
:
: class MyClass {
: has $attr; # no "dot"
: }

I don't think it has to imply that.

: What do you do when that happens? (Is that the way to do class vars?)

No, if it means anything, it means an attribute that doesn't have an
accessor method. But at the moment I don't think it means anything.

Maybe it's irrational, but I got sick and tired of looking at methods
in C++ and not knowing whether "foo" was an attribute or a variable.
So I'm not eager to put the same ambiguity into Perl. Secondary
sigils in Perl 6 are intentionally aimed at making scope and lifetime
distinctions visually explicit. More specifically, I'm trying to
make a distinction that many natural languages make between marked and
unmarked constructs. It's the unusual scopes and lifetimes that should
be considered marked. Ordinary variables don't need to be marked.
It's just a funny kind of Huffman coding, from a linguistic viewpoint.

Larry

0 new messages