Re: scopes of $?SELF and $?CLASS

0 views
Skip to first unread message

Stevan Little

unread,
Aug 17, 2005, 2:42:57 PM8/17/05
to Ingo Blechschmidt, perl6-l...@perl.org

On Aug 17, 2005, at 2:28 PM, Ingo Blechschmidt wrote:
> Hi,
>
> Stevan Little wrote:
>> So, onto my question, I am wondering what are the valid scopes for
>> $?SELF and $?CLASS.
>>
>> Are these (magical) globals who only have bound values in certain
>> contexts? If that is so, what value do they have outside of a valid
>> context? undef? or is attempting to accessing the value a runtime
>> exception?
>
> hm, I've thought of these as follows:
>
> class Foo {...} # is really
> class Foo {
> my $?CLASS := Foo;
> ...;
> }
>
> method bar($self:) {...} # is really
> method bar($self:) {
> my $?SELF := $self;
> ...;
> }

Yes, this is how I saw it too.

>> The obvious one is that they are both valid within a method. I asumme
>> that $?SELF is bound to the invocant, and $?CLASS is bound to the
>> class the method was defined within. It seems to me that this also
>> mean that in a class method, that $?SELF == $?CLASS?
>
> I think so, too.
>
>> Also (IIRC) we discussed $?CLASS being valid inside a class Foo { ...
>> } block at the hackathon. Would mean that something like this should
>> be possible.
>>
>> class FooLoggerProxy is Foo {
>> has Logger $.logger;
>> for ($?CLASS.meta.superclasses()) -> $super {
>> for ($super.meta.getmethods()) -> $method {
>> $?CLASS.meta.add_method($method.label => method {
>> $?SELF.logger.log($method.label ~ " has been
>> called"); return $method.do(*@_)
>> });
>> }
>> }
>> }
>
> I'd opt for yes.
>
>> I am not sure if there are any other valid contexts other than inside
>> a method or a class composition block. At least none that I can think
>> of.
>
> role, submethod?

I think in a Role, $?SELF would still be the invocant in a method, and
$?CLASS would (eventually) bind to the class the role was composed
into.

As for submethods, I see them like this:

submethod foo () { ... }

is really ..

submethod foo () {
next METHOD unless $?SELF ~~ $?CLASS;
}

At least that is how larry explained to me about a month ago.

Stevan


>
>
> --Ingo
>
> --
> Linux, the choice of a GNU | Mathematicians practice absolute freedom.
> generation on a dual AMD | -- Henry Adams
> Athlon! |
>
>

Stevan Little

unread,
Aug 17, 2005, 2:15:56 PM8/17/05
to Perl6 Language List
Hello all,

I tried to search for this answer in AES12, but I did not see anything,
and a perl6.lang search just brought up the whole $_.method vs.
./method debate (which was too much to shlog through).

So, onto my question, I am wondering what are the valid scopes for
$?SELF and $?CLASS.

Are these (magical) globals who only have bound values in certain
contexts? If that is so, what value do they have outside of a valid
context? undef? or is attempting to accessing the value a runtime
exception?

Or ...

Is it a syntax error to access them outside of a valid scope, and
therefore caught at compile time? In this case, then it seems to me
that they are not behaving as global variables so much as they are
behaving like language keywords.

Now as for the valid contexts.

The obvious one is that they are both valid within a method. I asumme
that $?SELF is bound to the invocant, and $?CLASS is bound to the class
the method was defined within. It seems to me that this also mean that
in a class method, that $?SELF == $?CLASS?

Also (IIRC) we discussed $?CLASS being valid inside a class Foo { ... }

block at the hackathon. Would mean that something like this should be
possible.

class FooLoggerProxy is Foo {
has Logger $.logger;
for ($?CLASS.meta.superclasses()) -> $super {
for ($super.meta.getmethods()) -> $method {
$?CLASS.meta.add_method($method.label => method {
$?SELF.logger.log($method.label ~ " has been called");
return $method.do(*@_)
});
}
}
}

I am not sure if there are any other valid contexts other than inside a

method or a class composition block. At least none that I can think of.

Thanks,

Stevan

Larry Wall

unread,
Aug 17, 2005, 2:47:00 PM8/17/05
to Perl6 Language List
On Wed, Aug 17, 2005 at 02:15:56PM -0400, Stevan Little wrote:
: So, onto my question, I am wondering what are the valid scopes for
: $?SELF and $?CLASS.
:
: Are these (magical) globals who only have bound values in certain
: contexts? If that is so, what value do they have outside of a valid
: context? undef? or is attempting to accessing the value a runtime
: exception?
:
: Or ...
:
: Is it a syntax error to access them outside of a valid scope, and
: therefore caught at compile time? In this case, then it seems to me
: that they are not behaving as global variables so much as they are
: behaving like language keywords.

They are variables known to the compiler but whose bindings change
during the course of the compile, so they tend to behave more like
lexically scoped entities, at least for any of them that the compiler
to save and restore. In a sense, they're lexical to the program
but dynamic to the compiler. So something like $?LINE does not
necessarily scope lexically, but the compiler does know where $?SELF
is valid and where it isn't, and which invocant to map it to when
it is valid.

: Now as for the valid contexts.


:
: The obvious one is that they are both valid within a method. I asumme
: that $?SELF is bound to the invocant, and $?CLASS is bound to the class
: the method was defined within. It seems to me that this also mean that
: in a class method, that $?SELF == $?CLASS?
:
: Also (IIRC) we discussed $?CLASS being valid inside a class Foo { ... }
: block at the hackathon. Would mean that something like this should be
: possible.
:
: class FooLoggerProxy is Foo {
: has Logger $.logger;
: for ($?CLASS.meta.superclasses()) -> $super {
: for ($super.meta.getmethods()) -> $method {
: $?CLASS.meta.add_method($method.label => method {
: $?SELF.logger.log($method.label ~ " has been called");
: return $method.do(*@_)
: });
: }
: }
: }
:
: I am not sure if there are any other valid contexts other than inside a
: method or a class composition block. At least none that I can think of.

If there are more they will become obvious as we go along. $? variables
that scope lexically are probably just "temp" or "let" variables in
the Perl grammar, so they won't be hard to monkey with if we need to.

Larry

Ingo Blechschmidt

unread,
Aug 17, 2005, 2:28:04 PM8/17/05
to perl6-l...@perl.org
Hi,

Stevan Little wrote:
> So, onto my question, I am wondering what are the valid scopes for
> $?SELF and $?CLASS.
>
> Are these (magical) globals who only have bound values in certain
> contexts? If that is so, what value do they have outside of a valid
> context? undef? or is attempting to accessing the value a runtime
> exception?

hm, I've thought of these as follows:

class Foo {...} # is really
class Foo {
my $?CLASS := Foo;
...;
}

method bar($self:) {...} # is really
method bar($self:) {
my $?SELF := $self;
...;
}

> The obvious one is that they are both valid within a method. I asumme


> that $?SELF is bound to the invocant, and $?CLASS is bound to the
> class the method was defined within. It seems to me that this also
> mean that in a class method, that $?SELF == $?CLASS?

I think so, too.

> Also (IIRC) we discussed $?CLASS being valid inside a class Foo { ...
> } block at the hackathon. Would mean that something like this should
> be possible.
>
> class FooLoggerProxy is Foo {
> has Logger $.logger;
> for ($?CLASS.meta.superclasses()) -> $super {
> for ($super.meta.getmethods()) -> $method {
> $?CLASS.meta.add_method($method.label => method {
> $?SELF.logger.log($method.label ~ " has been
> called"); return $method.do(*@_)
> });
> }
> }
> }

I'd opt for yes.

> I am not sure if there are any other valid contexts other than inside
> a method or a class composition block. At least none that I can think
> of.

role, submethod?

Larry Wall

unread,
Aug 17, 2005, 2:53:22 PM8/17/05
to perl6-l...@perl.org
On Wed, Aug 17, 2005 at 02:42:57PM -0400, Stevan Little wrote:
: I think in a Role, $?SELF would still be the invocant in a method, and
: $?CLASS would (eventually) bind to the class the role was composed
: into.

Yes, such things stay generic as long as they need to, and no longer.

: As for submethods, I see them like this:


:
: submethod foo () { ... }
:
: is really ..
:
: submethod foo () {
: next METHOD unless $?SELF ~~ $?CLASS;
: }
:
: At least that is how larry explained to me about a month ago.

Can't use ~~ for that, since ~~ implies "does", which is not an
exact class match. Probably need

next METHOD unless $?SELF.class =:= $?CLASS;

or some such. Except that BUILDALL/DESTROYALL have to be able to
invoke submethods on partial objects whose actual class is not the
same as the submethod, so there needs to be some way of forcing
$?SELF to consider itself in $?CLASS temporarily for infrastructural
purposes. Maybe it's as easy as "temp $obj.class := $tmpclass"
in the BUILDALL/DESTROYALL dispatcher. I dunno.

Larry

Stevan Little

unread,
Aug 17, 2005, 6:26:02 PM8/17/05
to Larry Wall, perl6-l...@perl.org
Larry,

On Aug 17, 2005, at 2:53 PM, Larry Wall wrote:
> : As for submethods, I see them like this:
> :
> : submethod foo () { ... }
> :
> : is really ..
> :
> : submethod foo () {
> : next METHOD unless $?SELF ~~ $?CLASS;
> : }
> :
> : At least that is how larry explained to me about a month ago.
>
> Can't use ~~ for that, since ~~ implies "does", which is not an
> exact class match. Probably need
>
> next METHOD unless $?SELF.class =:= $?CLASS;
>
> or some such.

In the 2.0 version of the metamodel I compare the class object's .id to
the instance's class object's .id. Which is (I assume) how =:= would do
it under the hood.

> Except that BUILDALL/DESTROYALL have to be able to
> invoke submethods on partial objects whose actual class is not the
> same as the submethod, so there needs to be some way of forcing
> $?SELF to consider itself in $?CLASS temporarily for infrastructural
> purposes. Maybe it's as easy as "temp $obj.class := $tmpclass"
> in the BUILDALL/DESTROYALL dispatcher. I dunno.

I am not sure if changing classes makes sense here so much as just
providing a means for submethod calls to be forced. Currently the
metamodels do this by allowing a special parameter in the first
argument which is a flag to let the submethod wrapper know if can skip
the "next METHOD" branch. It is a bit of a kludge, but it seems to
work.

The other option I considered was to make BUILDALL and DESTORYALL
special somehow. But I am not sure if this makes any more sense than
the kludge described above.

Stevan


>
> Larry
>

Larry Wall

unread,
Aug 17, 2005, 8:07:45 PM8/17/05
to perl6-l...@perl.org
On Wed, Aug 17, 2005 at 06:26:02PM -0400, Stevan Little wrote:
: I am not sure if changing classes makes sense here so much as just
: providing a means for submethod calls to be forced. Currently the
: metamodels do this by allowing a special parameter in the first
: argument which is a flag to let the submethod wrapper know if can skip
: the "next METHOD" branch. It is a bit of a kludge, but it seems to
: work.
:
: The other option I considered was to make BUILDALL and DESTORYALL
: special somehow. But I am not sure if this makes any more sense than
: the kludge described above.

I'm not sure it's a kludge. I think it might just be a specific
subcase of the "I've already checked the parameters to this, just
let me call you as a bare sub" entry point. So maybe it's the same
alternate entry point used by the junction threading code after it's
already figured out how to thread. A lot of optimizations might want
that bare entry point as well.

This does imply that the "next METHOD" of a submethod is outside that
bare entry point, of course. That's what your flag is emulating.

Larry

Reply all
Reply to author
Forward
0 new messages