scopes of $?SELF and $?CLASS
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([EMAIL PROTECTED]) }); } } } 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
Re: scopes of $?SELF and $?CLASS
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([EMAIL PROTECTED]) }); } } } 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? --Ingo -- Linux, the choice of a GNU | Mathematicians practice absolute freedom. generation on a dual AMD | -- Henry Adams Athlon!|
Re: scopes of $?SELF and $?CLASS
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([EMAIL PROTECTED]) }); } } } 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!|
Re: scopes of $?SELF and $?CLASS
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([EMAIL PROTECTED]) : }); : } : } : } : : 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
Re: scopes of $?SELF and $?CLASS
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
Re: scopes of $?SELF and $?CLASS
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
Re: scopes of $?SELF and $?CLASS
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